diff --git a/COPYING b/COPYING new file mode 120000 index 00000000..7a694c96 --- /dev/null +++ b/COPYING @@ -0,0 +1 @@ +LICENSE \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..7a4a3ea2 --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 00000000..db04346c --- /dev/null +++ b/Makefile.am @@ -0,0 +1,20 @@ +########################################################################## +# If not stated otherwise in this file or this component's Licenses.txt +# file the following copyright and licenses apply: +# +# Copyright 2017 RDK Management +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +########################################################################## + +SUBDIRS = source diff --git a/NOTICE b/NOTICE new file mode 100644 index 00000000..dd79f295 --- /dev/null +++ b/NOTICE @@ -0,0 +1,11 @@ +This component contains software that is Copyright (c) 2020 RDK Management. +The component is licensed to you under the Apache License, Version 2.0 (the "License"). +You may not use the component except in compliance with the License. + +The component may include material which is licensed under other licenses / copyrights as +listed below. Your use of this material within the component is also subject to the terms and +conditions of these licenses. The LICENSE file contains the text of all the licenses which apply +within this component. + +Copyright 2014 Cisco Systems, Inc. +Licensed under the Apache License, Version 2.0 diff --git a/cfg/Makefile.am b/cfg/Makefile.am new file mode 100644 index 00000000..b2f4e598 --- /dev/null +++ b/cfg/Makefile.am @@ -0,0 +1,22 @@ +########################################################################## +# If not stated otherwise in this file or this component's Licenses.txt +# file the following copyright and licenses apply: +# +# Copyright 2017 RDK Management +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +########################################################################## + +SUBDIRS = +DIST_SUBDIRS = + diff --git a/cmpnt_build_custom_pre.mk b/cmpnt_build_custom_pre.mk new file mode 100644 index 00000000..f08acb95 --- /dev/null +++ b/cmpnt_build_custom_pre.mk @@ -0,0 +1,51 @@ +########################################################################## +# If not stated otherwise in this file or this component's Licenses.txt +# file the following copyright and licenses apply: +# +# Copyright 2017 RDK Management +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +########################################################################## +####################################################################### +# Copyright [2014] [Cisco Systems, Inc.] +# +# Licensed under the Apache License, Version 2.0 (the \"License\"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an \"AS IS\" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +####################################################################### + +# +# component list +# + +PNM_BUILD_TR_181=1 +PNM_BUILD_TR_135=0 +PNM_BUILD_TR_098=0 +PNM_BUILD_Xcalibur=0 + +# +# platform specific customization +# + + +#UTOPIA_LDFLAGS = -L$(SDK_PATH)/ti/lib -lsyscfg -lsysevent -lulog +#LDFLAGS += $(UTOPIA_LDFLAGS) + diff --git a/config/RdkWanManager.xml b/config/RdkWanManager.xml new file mode 100644 index 00000000..d00fbb53 --- /dev/null +++ b/config/RdkWanManager.xml @@ -0,0 +1,1244 @@ + + + + 1 + TR181_RdkWanManager + + + + + + X_RDK_WanManager + object + + WanManager_GetParamUlongValue + WanManager_SetParamUlongValue + WanManager_GetParamStringValue + WanManager_SetParamStringValue + WanManager_GetParamBoolValue + WanManager_SetParamBoolValue + WanManager_Validate + WanManager_Commit + + + + Enable + boolean + bool + true + + + Policy + string: FIXED_MODE_ON_BOOTUP(1),FIXED_MODE(2),PRIMARY_PRIORITY_ON_BOOTUP(3),PRIMARY_PRIORITY(4),MULTIWAN_MODE(5) + uint32/mapped + true + + + IdleTimeout + unsignedInt + uint32 + true + + + + + CPEInterface + staticTable + 128 + + WanIf_GetEntryCount + WanIf_GetEntry + WanIf_GetParamStringValue + WanIf_SetParamStringValue + WanIf_Validate + WanIf_Commit + WanIf_Rollback + + + + Name + string + string + true + + + DisplayName + string + string + true + + + + + Phy + object + + WanIfPhy_GetParamUlongValue + WanIfPhy_GetParamStringValue + WanIfPhy_SetParamUlongValue + WanIfPhy_SetParamStringValue + WanIfPhy_Validate + WanIfPhy_Commit + WanIfPhy_Rollback + + + + Path + string + string + true + + + Status + string: Down(1),Initializing(2),Up(3) + uint32/mapped + true + + + + + + Wan + object + + WanIfCfg_GetParamUlongValue + WanIfCfg_SetParamUlongValue + WanIfCfg_GetParamIntValue + WanIfCfg_SetParamIntValue + WanIfCfg_GetParamBoolValue + WanIfCfg_SetParamBoolValue + WanIfCfg_GetParamStringValue + WanIfCfg_SetParamStringValue + WanIfCfg_Validate + WanIfCfg_Commit + WanIfCfg_Rollback + + + + Enable + boolean + bool + true + + + Name + string + string + true + + + SelectionTimeout + unsignedInt + uint32 + true + + + EnableMAPT + boolean + bool + true + + + EnableDSLite + boolean + bool + true + + + EnableIPoEHealthCheck + boolean + bool + true + + + Type + string: Unconfigured(1),Primary(2),Secondary(3) + uint32/mapped + true + + + Priority + int + int + true + + + Status + string: Disabled(1),Initialising(2),Validating(3), Up(4) + uint32/mapped + false + + + Refresh + boolean + bool + true + + + ActiveLink + boolean + bool + true + + + LinkStatus + string: Down(1),Configuring(2),Up(3) + uint32/mapped + true + + + + + Validation + object + + WanIfValidation_GetParamBoolValue + WanIfValidation_SetParamBoolValue + WanIfValidation_Validate + WanIfValidation_Commit + WanIfValidation_Rollback + + + + Discovery-Offer + boolean + bool + true + + + Solicit-Advertise + boolean + bool + true + + + RS-RA + boolean + bool + true + + + PADI-PADO + boolean + bool + true + + + + + + + DynamicTrigger + object + + WanIfDynTrigger_GetParamUlongValue + WanIfDynTrigger_SetParamUlongValue + WanIfDynTrigger_GetParamBoolValue + WanIfDynTrigger_SetParamBoolValue + WanIfDynTrigger_Validate + WanIfDynTrigger_Commit + WanIfDynTrigger_Rollback + + + + Enable + boolean + bool + true + + + Delay + unsignedInt + uint32 + true + + + + + IP + object + + WanIfIpCfg_GetParamUlongValue + WanIfIpCfg_SetParamUlongValue + WanIfIpCfg_GetParamStringValue + WanIfIpCfg_SetParamStringValue + WanIfIpCfg_Validate + WanIfIpCfg_Commit + WanIfIpCfg_Rollback + + + + IPv4Status + string: Up(1),Down(2) + uint32/mapped + true + + + IPv6Status + string: Up(1),Down(2) + uint32/mapped + true + + + Path + string + string + true + + + + + PPP + object + + WanIfPPPCfg_GetParamUlongValue + WanIfPPPCfg_SetParamUlongValue + WanIfPPPCfg_GetParamStringValue + WanIfPPPCfg_SetParamStringValue + WanIfPPPCfg_GetParamBoolValue + WanIfPPPCfg_SetParamBoolValue + WanIfPPPCfg_Validate + WanIfPPPCfg_Commit + WanIfPPPCfg_Rollback + + + + Enable + boolean + bool + true + + + IPCPEnable + boolean + bool + true + + + IPCPStatus + string: Down(1),Up(2) + uint32/mapped + true + + + IPv6CPEnable + boolean + bool + true + + + IPv6CPStatus + string: Down(1),Up(2) + uint32/mapped + true + + + LCPStatus + string: Down(1),Up(2) + uint32/mapped + true + + + LinkStatus + string: Down(1),Up(2) + uint32/mapped + true + + + LinkType + string: PPPoA(1),PPPoE(2) + uint32/mapped + true + + + Path + string + string + true + + + + + MAP + object + + WanIfMapt_GetParamUlongValue + WanIfMapt_SetParamUlongValue + WanIfMapt_GetParamStringValue + WanIfMapt_SetParamStringValue + WanIfMapt_Validate + WanIfMapt_Commit + WanIfMapt_Rollback + + + + MAPTStatus + string: Up(1),Down(2) + uint32/mapped + true + + + Path + string + string + true + + + + + DSLite + object + + WanIfDSLite_GetParamUlongValue + WanIfDSLite_SetParamUlongValue + WanIfDSLite_GetParamStringValue + WanIfDSLite_SetParamStringValue + WanIfDSLite_Validate + WanIfDSLite_Commit + WanIfDSLite_Rollback + + + + Status + string: Up(1),Down(2) + uint32/mapped + true + + + Path + string + string + true + + + + + Marking + writableTable + 128 + + Marking_GetEntryCount + Marking_GetEntry + Marking_AddEntry + Marking_DelEntry + Marking_GetParamIntValue + Marking_GetParamUlongValue + Marking_GetParamStringValue + Marking_GetParamIntValue + Marking_SetParamIntValue + Marking_SetParamUlongValue + Marking_SetParamStringValue + Marking_Validate + Marking_Commit + Marking_Rollback + + + + Alias + string(64) + string + true + + + SKBPort + unsignedInt + uint32 + + + SKBMark + unsignedInt + uint32 + + + EthernetPriorityMark + int + int + true + + + + + + + + + + DHCPv4 + + object + + + + DHCPv4_GetParamBoolValue + + DHCPv4_GetParamIntValue + + DHCPv4_GetParamUlongValue + + DHCPv4_GetParamStringValue + + + + + + + ClientNumberOfEntries + + unsignedInt + + uint32 + + + + + + + + Client + + writableTable + + 128 + + + + Client_GetEntryCount + + Client_GetEntry + + Client_AddEntry + + Client_DelEntry + + Client_GetParamBoolValue + + Client_GetParamIntValue + + Client_GetParamUlongValue + + Client_GetParamStringValue + + Client_SetParamBoolValue + + Client_SetParamIntValue + + Client_SetParamUlongValue + + Client_SetParamStringValue + + Client_Validate + + Client_Commit + + Client_Rollback + + + + + + + + Enable + + boolean + + bool + + true + + + + + + Alias + + string(64) + + string + + true + + + + + + X_CISCO_COM_BootFileName + + string(256) + + string + + true + + + + + + Interface + + string(256) + + string + + true + + + + + + Status + + string: Disabled(1),Enabled(2),Error_Misconfigured(3),Error(4) + + uint32/mapped + + + + + + DHCPStatus + + string: Init(1),Selecting(2),Requesting(3),Rebinding(4),Bound(5),Renewing(6) + + uint32/mapped + + + + + + Renew + + boolean + + bool + + true + + + + + + IPAddress + + string + + uint32/ip4_addr + + + + + + SubnetMask + + string + + uint32/ip4_addr + + + + + + IPRouters + + string(256) + + string + + + + + + DNSServers + + string(256) + + string + + + + + + LeaseTimeRemaining + + int[-1:] + + int + + off + + + + + + DHCPServer + + string + + uint32/ip4_addr + + + + + + SentOptionNumberOfEntries + + unsignedInt + + uint32 + + + + + + ReqOptionNumberOfEntries + + unsignedInt + + uint32 + + + + + + + + + + SentOption + + writableTable + + 128 + + + + SentOption_GetEntryCount + + SentOption_GetEntry + + SentOption_AddEntry + + SentOption_DelEntry + + SentOption_GetParamBoolValue + + SentOption_GetParamIntValue + + SentOption_GetParamUlongValue + + SentOption_GetParamStringValue + + SentOption_SetParamBoolValue + + SentOption_SetParamIntValue + + SentOption_SetParamUlongValue + + SentOption_SetParamStringValue + + SentOption_Validate + + SentOption_Commit + + SentOption_Rollback + + + + + + + + Enable + + boolean + + bool + + true + + + + + + Alias + + string(64) + + string + + true + + + + + + Tag + + unsignedInt[1:254] + + uint32 + + true + + + + + + Value + + hexBinary(255) + + string + + true + + + + + + + + + + ReqOption + + writableTable + + 128 + + + + ReqOption_GetEntryCount + + ReqOption_GetEntry + + ReqOption_AddEntry + + ReqOption_DelEntry + + ReqOption_GetParamBoolValue + + ReqOption_GetParamIntValue + + ReqOption_GetParamUlongValue + + ReqOption_GetParamStringValue + + ReqOption_SetParamBoolValue + + ReqOption_SetParamIntValue + + ReqOption_SetParamUlongValue + + ReqOption_SetParamStringValue + + ReqOption_Validate + + ReqOption_Commit + + ReqOption_Rollback + + + + + + + + Enable + + boolean + + bool + + true + + + + + + Order + + unsignedInt[1:] + + uint32 + + true + + + + + + Alias + + string(64) + + string + + true + + + + + + Tag + + unsignedInt[1:254] + + uint32 + + true + + + + + + Value + + hexBinary(255) + + string + + true + + + + + + + + + + + + + + DHCPv6 + object + + DHCPv6_GetParamBoolValue + DHCPv6_GetParamIntValue + DHCPv6_GetParamUlongValue + DHCPv6_GetParamStringValue + + + + ClientNumberOfEntries + unsignedInt + uint32 + + + + + Client + writableTable + 128 + + Client3_GetEntryCount + Client3_GetEntry + Client3_AddEntry + Client3_DelEntry + Client3_GetParamBoolValue + Client3_GetParamIntValue + Client3_GetParamUlongValue + Client3_GetParamStringValue + Client3_SetParamBoolValue + Client3_SetParamIntValue + Client3_SetParamUlongValue + Client3_SetParamStringValue + Client3_Validate + Client3_Commit + Client3_Rollback + + + + Enable + boolean + bool + true + + + Alias + string(64) + string + true + + + Interface + string(256) + string + true + + + Status + string: Disabled(1),Enabled(2),Error_Misconfigured(3),Error(4) + uint32/mapped + + + DUID + hexBinary(130) + string + + + RequestAddresses + boolean + bool + true + + + RequestPrefixes + boolean + bool + true + + + RapidCommit + boolean + bool + true + + + Renew + boolean + bool + true + + + SuggestedT1 + int[-1:] + int + true + + + SuggestedT2 + int[-1:] + int + true + + + SupportedOptions + string + string + + + RequestedOptions + string + string + true + + + ServerNumberOfEntries + unsignedInt + uint32 + + + SentOptionNumberOfEntries + unsignedInt + uint32 + + + ReceivedOptionNumberOfEntries + unsignedInt + uint32 + + + + + Server + dynamicTable + 128 + + Server2_GetEntryCount + Server2_GetEntry + Server2_IsUpdated + Server2_Synchronize + Server2_GetParamBoolValue + Server2_GetParamIntValue + Server2_GetParamUlongValue + Server2_GetParamStringValue + + + + SourceAddress + string + string + + + DUID + hexBinary(130) + string + + + InformationRefreshTime + dateTime + string + + + + + SentOption + writableTable + 128 + + SentOption1_GetEntryCount + SentOption1_GetEntry + SentOption1_AddEntry + SentOption1_DelEntry + SentOption1_GetParamBoolValue + SentOption1_GetParamIntValue + SentOption1_GetParamUlongValue + SentOption1_GetParamStringValue + SentOption1_SetParamBoolValue + SentOption1_SetParamIntValue + SentOption1_SetParamUlongValue + SentOption1_SetParamStringValue + SentOption1_Validate + SentOption1_Commit + SentOption1_Rollback + + + + Enable + boolean + bool + true + + + Alias + string(64) + string + true + + + Tag + unsignedInt[0:65535] + uint32 + true + + + Value + hexBinary(65535) + string + true + + + + + ReceivedOption + dynamicTable + 128 + + ReceivedOption_GetEntryCount + ReceivedOption_GetEntry + ReceivedOption_IsUpdated + ReceivedOption_Synchronize + ReceivedOption_GetParamBoolValue + ReceivedOption_GetParamIntValue + ReceivedOption_GetParamUlongValue + ReceivedOption_GetParamStringValue + + + + Tag + unsignedInt[0:65535] + uint32 + + + Value + hexBinary(65535) + string + + + Server + string + string + + + + + + X_RDKCENTRAL-COM_RcvOption + object + + dhcp6c_mapt_mape_GetParamBoolValue + dhcp6c_mapt_mape_GetParamUlongValue + dhcp6c_mapt_mape_GetParamStringValue + + + + MapTransportMode + string + string + false + + + MapBRPrefix + string + string + false + + + MapRuleIPv4Prefix + string + string + false + + + MapRuleIPv6Prefix + string + string + false + + + MapEALen + unsignedInt + uint32 + false + + + MapPSIDOffset + unsignedInt + uint32 + + + MapPSIDLen + unsignedInt + uint32 + false + + + MapPSID + unsignedInt + uint32 + false + + + MapIsFMR + boolean + bool + false + + + + + + + + + diff --git a/configure.ac b/configure.ac new file mode 100644 index 00000000..c5116cf2 --- /dev/null +++ b/configure.ac @@ -0,0 +1,91 @@ +########################################################################## +# If not stated otherwise in this file or this component's Licenses.txt +# file the following copyright and licenses apply: +# +# Copyright 2017 RDK Management +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +########################################################################## +dnl -*- Autoconf -*- +dnl Process this file with autoconf to produce a configure script. + +dnl AC_PREREQ([2.69]) +AC_INIT(RdkWanManager-rdkb, version-1.0) +AC_CONFIG_SRCDIR([]) +AM_CONFIG_HEADER(cfg/config.h) +AC_CONFIG_MACRO_DIR([cfg]) +AC_CONFIG_AUX_DIR([cfg]) +AM_INIT_AUTOMAKE([foreign no-dist-gzip dist-bzip2 1.9]) +LT_INIT + +dnl subdirectories. +SUBDIRS="" + +dnl Checks for programs. +AC_PROG_CXX +AC_PROG_CC +AC_PROG_INSTALL +AC_PROG_LN_S +AC_PROG_CPP +AC_PROG_CXXCPP + +dnl use pretty build output with automake >= 1.11 +m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])], + [AM_DEFAULT_VERBOSITY=1 + AC_SUBST(AM_DEFAULT_VERBOSITY)]) + + + + +dnl ********************************** +dnl checks for dependencies +dnl ********************************** +AC_HEADER_STDC + +SYSTEMD_CFLAGS=" " +SYSTEMD_LDFLAGS=" " + +AC_ARG_ENABLE([notify], + AS_HELP_STRING([--enable-notify],[enable systemd notify]), + [ + case "${enableval}" in + yes) SYSTEMD_CFLAGS="-DENABLE_SD_NOTIFY" + SYSTEMD_LDFLAGS="-lsystemd" ;; + no) AC_MSG_ERROR([systemd notify is disabled]) ;; + *) AC_MSG_ERROR([bad value ${enableval} for --enable-notify ]) ;; + esac + ], + [echo "systemd notify is disabled."]) + +AC_SUBST(SYSTEMD_CFLAGS) +AC_SUBST(SYSTEMD_LDFLAGS) + +dnl Checks for header files. +AC_CHECK_HEADERS([limits.h memory.h stdlib.h string.h sys/socket.h unistd.h]) + +dnl Checks for typedefs, structures, and compiler characteristics. +dnl AC_CHECK_HEADER_STDBOOL +AC_TYPE_UINT8_T + +dnl Checks for library functions. +AC_FUNC_MALLOC +AC_CHECK_FUNCS([memset strdup strerror]) + +PKG_CHECK_MODULES([DBUS],[dbus-1 >= 1.6.18]) + +AC_CONFIG_FILES([Makefile + source/Makefile + source/TR-181/Makefile + source/TR-181/middle_layer_src/Makefile + source/WanManager/Makefile]) +AC_OUTPUT diff --git a/source/Makefile.am b/source/Makefile.am new file mode 100644 index 00000000..fb8a9cf9 --- /dev/null +++ b/source/Makefile.am @@ -0,0 +1,20 @@ +########################################################################## +# If not stated otherwise in this file or this component's Licenses.txt +# file the following copyright and licenses apply: +# +# Copyright 2017 RDK Management +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +########################################################################## + +SUBDIRS = TR-181 WanManager diff --git a/source/TR-181/Makefile.am b/source/TR-181/Makefile.am new file mode 100644 index 00000000..66a8cdbc --- /dev/null +++ b/source/TR-181/Makefile.am @@ -0,0 +1,20 @@ +########################################################################## +# If not stated otherwise in this file or this component's Licenses.txt +# file the following copyright and licenses apply: +# +# Copyright 2015 RDK Management +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +########################################################################## + +SUBDIRS = middle_layer_src diff --git a/source/TR-181/include/dmsb_tr181_psm_definitions.h b/source/TR-181/include/dmsb_tr181_psm_definitions.h new file mode 100644 index 00000000..a3578332 --- /dev/null +++ b/source/TR-181/include/dmsb_tr181_psm_definitions.h @@ -0,0 +1,61 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2015 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +#ifndef _DMSB_TR181_PSM_DEFINITIONS_ +#define _DMSB_TR181_PSM_DEFINITIONS_ + +/********************************************************************** + X_RDK_WanManager. +**********************************************************************/ +#define PSM_WANMANAGER_WANENABLE "dmsb.wanmanager.wanenable" +#define PSM_WANMANAGER_WANMODE "dmsb.wanmanager.wanmode" +#define PSM_WANMANAGER_WANPOLICY "dmsb.wanmanager.wanpolicy" +#define PSM_WANMANAGER_WANIFCOUNT "dmsb.wanmanager.wanifcount" +#define PSM_WANMANAGER_WANIDLETIMEOUT "dmsb.wanmanager.wanidletimeout" +#define PSM_WANMANAGER_IF_ENABLE "dmsb.wanmanager.if.%d.Enable" +#define PSM_WANMANAGER_IF_NAME "dmsb.wanmanager.if.%d.Name" +#define PSM_WANMANAGER_IF_DISPLAY_NAME "dmsb.wanmanager.if.%d.DisplayName" +#define PSM_WANMANAGER_IF_TYPE "dmsb.wanmanager.if.%d.Type" +#define PSM_WANMANAGER_IF_PRIORITY "dmsb.wanmanager.if.%d.Priority" +#define PSM_WANMANAGER_IF_SELECTIONTIMEOUT "dmsb.wanmanager.if.%d.SelectionTimeout" +#define PSM_WANMANAGER_IF_DYNTRIGGERENABLE "dmsb.wanmanager.if.%d.DynTriggerEnable" +#define PSM_WANMANAGER_IF_DYNTRIGGERDELAY "dmsb.wanmanager.if.%d.DynTriggerDelay" +#define PSM_WANMANAGER_IF_WAN_ENABLE_MAPT "dmsb.wanmanager.if.%d.EnableMAPT" +#define PSM_WANMANAGER_IF_WAN_ENABLE_DSLITE "dmsb.wanmanager.if.%d.EnableDSLite" +#define PSM_WANMANAGER_IF_WAN_ENABLE_IPOE "dmsb.wanmanager.if.%d.EnableIPoE" +#define PSM_WANMANAGER_IF_WAN_VALIDATION_DISCOVERY_OFFER "dmsb.wanmanager.if.%d.Validation.DiscoveryOffer" +#define PSM_WANMANAGER_IF_WAN_VALIDATION_SOLICIT_ADVERTISE "dmsb.wanmanager.if.%d.Validation.SolicitAdvertise" +#define PSM_WANMANAGER_IF_WAN_VALIDATION_RS_RA "dmsb.wanmanager.if.%d.Validation.RsRa" +#define PSM_WANMANAGER_IF_WAN_VALIDATION_PADI_PADO "dmsb.wanmanager.if.%d.Validation.PadiPado" +#define PSM_WANMANAGER_IF_WAN_PPP_ENABLE "dmsb.wanmanager.if.%d.PPPEnable" +#define PSM_WANMANAGER_IF_WAN_PPP_LINKTYPE "dmsb.wanmanager.if.%d.PPPLinkType" +#define PSM_WANMANAGER_IF_WAN_PPP_IPCP_ENABLE "dmsb.wanmanager.if.%d.PPPIPCPEnable" +#define PSM_WANMANAGER_IF_WAN_PPP_IPV6CP_ENABLE "dmsb.wanmanager.if.%d.PPPIPV6CPEnable" +#define PSM_SELFHEAL_REBOOT_STATUS "dmsb.selfheal.rebootstatus" + +/********************************************************************** + Interface.{i}.Marking.{i}. +**********************************************************************/ +#define PSM_MARKING_LIST "dmsb.wanmanager.if.%d.Marking.List" +#define PSM_MARKING_ALIAS "dmsb.wanmanager.if.%d.Marking.%s.Alias" +#define PSM_MARKING_SKBPORT "dmsb.wanmanager.if.%d.Marking.%s.SKBPort" +#define PSM_MARKING_SKBMARK "dmsb.wanmanager.if.%d.Marking.%s.SKBMark" +#define PSM_MARKING_ETH_PRIORITY_MASK "dmsb.wanmanager.if.%d.Marking.%s.EthernetPriorityMark" + +#endif diff --git a/source/TR-181/include/wanmgr_apis.h b/source/TR-181/include/wanmgr_apis.h new file mode 100644 index 00000000..f6df0c66 --- /dev/null +++ b/source/TR-181/include/wanmgr_apis.h @@ -0,0 +1,35 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2015 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +#ifndef _WANMGR_APIS_H_ +#define _WANMGR_APIS_H_ + +#include "wanmgr_rdkbus_common.h" +#include "wanmgr_plugin_main_apis.h" + +/********************************************************************** + STRUCTURE AND CONSTANT DEFINITIONS +**********************************************************************/ + + +/********************************************************************** + FUNCTION PROTOTYPES +**********************************************************************/ + +#endif //_WANMGR_APIS_H_ diff --git a/source/TR-181/include/wanmgr_dml.h b/source/TR-181/include/wanmgr_dml.h new file mode 100644 index 00000000..fe519ee6 --- /dev/null +++ b/source/TR-181/include/wanmgr_dml.h @@ -0,0 +1,327 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2015 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +#ifndef _WANMGR_DML_H_ +#define _WANMGR_DML_H_ + +#include "ipc_msg.h" + +#define PAM_COMPONENT_NAME "eRT.com.cisco.spvtg.ccsp.pam" +#define PAM_DBUS_PATH "/com/cisco/spvtg/ccsp/pam" +#define PAM_NOE_PARAM_NAME "Device.IP.InterfaceNumberOfEntries" +#define PAM_IF_TABLE_OBJECT "Device.IP.Interface.%d." +#define PAM_IF_PARAM_NAME "Device.IP.Interface.%d.Name" +#define DML_WAN_IFACE_PRIORITY_MAX 255 + +typedef enum _DML_WAN_POLICY +{ + FIXED_MODE_ON_BOOTUP = 1, + FIXED_MODE, + PRIMARY_PRIORITY_ON_BOOTUP, + PRIMARY_PRIORITY, + MULTIWAN_MODE +} DML_WAN_POLICY; + + +typedef enum _DML_WAN_IFACE_STATUS +{ + WAN_IFACE_STATUS_DISABLED = 1, + WAN_IFACE_STATUS_INITIALISING, + WAN_IFACE_STATUS_VALIDATING, + WAN_IFACE_STATUS_UP +} DML_WAN_IFACE_STATUS; + +typedef enum _DML_WAN_IFACE_LINKSTATUS +{ + WAN_IFACE_LINKSTATUS_DOWN = 1, + WAN_IFACE_LINKSTATUS_CONFIGURING, + WAN_IFACE_LINKSTATUS_UP +} DML_WAN_IFACE_LINKSTATUS; +typedef enum _WAN_MANAGER_STATUS +{ + WAN_MANAGER_DOWN = 1, + WAN_MANAGER_UP +} WAN_MANAGER_STATUS; + +/** enum wan iface phy status */ +typedef enum _DML_WAN_IFACE_PHY_STATUS +{ + WAN_IFACE_PHY_STATUS_DOWN = 1, + WAN_IFACE_PHY_STATUS_INITIALIZING, + WAN_IFACE_PHY_STATUS_UP +} DML_WAN_IFACE_PHY_STATUS; + +/** enum wan status */ +typedef enum _DML_WAN_IFACE_TYPE +{ + WAN_IFACE_TYPE_UNCONFIGURED = 1, + WAN_IFACE_TYPE_PRIMARY, + WAN_IFACE_TYPE_SECONDARY +} DML_WAN_IFACE_TYPE; + +/** enum wan status */ +typedef enum _DML_WAN_IFACE_IPV4_STATUS +{ + WAN_IFACE_IPV4_STATE_UP = 1, + WAN_IFACE_IPV4_STATE_DOWN +} DML_WAN_IFACE_IPV4_STATUS; + +/** enum wan status */ +typedef enum _DML_WAN_IFACE_IPV6_STATUS +{ + WAN_IFACE_IPV6_STATE_UP = 1, + WAN_IFACE_IPV6_STATE_DOWN +} DML_WAN_IFACE_IPV6_STATUS; + +/** enum wan status */ +typedef enum _DML_WAN_IFACE_MAPT_STATUS +{ + WAN_IFACE_MAPT_STATE_UP = 1, + WAN_IFACE_MAPT_STATE_DOWN +} DML_WAN_IFACE_MAPT_STATUS; + +/** enum dslite status */ +typedef enum _DML_WAN_IFACE_DSLITE_STATUS +{ + WAN_IFACE_DSLITE_STATE_UP = 1, + WAN_IFACE_DSLITE_STATE_DOWN +} DML_WAN_IFACE_DSLITE_STATUS; + +/** enum wan status */ +typedef enum _WAN_NOTIFY_ENUM +{ + NOTIFY_TO_VLAN_AGENT = 1 +} WAN_NOTIFY_ENUM; + +/** Enum IP (IPV4/IPV6/MAPT) state type. **/ +typedef enum _DML_WAN_IFACE_IP_STATE_TYPE +{ + WAN_IFACE_IPV4_STATE = 0, + WAN_IFACE_IPV6_STATE, + WAN_IFACE_MAPT_STATE, + WAN_IFACE_DSLITE_STATE +} DML_WAN_IFACE_IP_STATE_TYPE; + +/** Enum IP state. UP/DOWN */ +typedef enum _DML_WAN_IFACE_IP_STATE +{ + WAN_IFACE_IP_STATE_UP = 1, + WAN_IFACE_IP_STATE_DOWN, +} DML_WAN_IFACE_IP_STATE; +/* + * Wan Marking object + */ +typedef enum _DML_WAN_MARKING_DML_OPERATIONS +{ + WAN_MARKING_ADD = 1, + WAN_MARKING_DELETE, + WAN_MARKING_UPDATE +} DML_WAN_MARKING_DML_OPERATIONS; + +typedef struct _DML_MARKING +{ + ULONG InstanceNumber; + ULONG ulWANIfInstanceNumber; + CHAR Alias[BUFLEN_64]; + UINT SKBPort; + UINT SKBMark; + INT EthernetPriorityMark; +} DML_MARKING; + +typedef struct _DATAMODEL_MARKING +{ + SLIST_HEADER MarkingList; + ULONG ulNextInstanceNumber; +} DATAMODEL_MARKING; + +/*** RDK WAN Interface ***/ +typedef struct _DML_WANIFACE_PHY +{ + CHAR Path[BUFLEN_64]; + DML_WAN_IFACE_PHY_STATUS Status; +} DML_WANIFACE_PHY; + +typedef enum _DML_WAN_IFACE_IPCP_STATUS +{ + WAN_IFACE_IPCP_STATUS_DOWN = 1, + WAN_IFACE_IPCP_STATUS_UP +} DML_WAN_IFACE_IPCP_STATUS; + +typedef enum _DML_WAN_IFACE_IPV6CP_STATUS +{ + WAN_IFACE_IPV6CP_STATUS_DOWN = 1, + WAN_IFACE_IPV6CP_STATUS_UP, +} DML_WAN_IFACE_IPV6CP_STATUS; + +typedef enum _DML_WAN_IFACE_LCP_STATUS +{ + WAN_IFACE_LCP_STATUS_DOWN = 1, + WAN_IFACE_LCP_STATUS_UP, +} DML_WAN_IFACE_LCP_STATUS; + +typedef enum _DML_WAN_IFACE_PPP_LINK_STATUS +{ + WAN_IFACE_PPP_LINK_STATUS_DOWN = 1, + WAN_IFACE_PPP_LINK_STATUS_UP, +} DML_WAN_IFACE_PPP_LINK_STATUS; + +typedef enum _DML_WAN_IFACE_LINK_TYPE +{ + WAN_IFACE_PPP_LINK_TYPE_PPPoA = 1, + WAN_IFACE_PPP_LINK_TYPE_PPPoE, +} DML_WAN_IFACE_LINK_TYPE; + +typedef enum _PPP_CONNECTION_EVENTS +{ + PPP_LINK_STATE_CHANGED = 1, + PPP_LCP_STATE_CHANGED, + PPP_IPCP_STATE_CHANGED, + PPP_IPV6CP_STATE_CHANGED +} DML_PPP_STATE_CHANGED_EVENTS; + +typedef struct _DATAMODEL_PPP +{ + BOOL Enable; + CHAR Path[BUFLEN_64]; + BOOL IPCPEnable; + BOOL IPV6CPEnable; + DML_WAN_IFACE_IPCP_STATUS IPCPStatus; + DML_WAN_IFACE_IPV6CP_STATUS IPV6CPStatus; + DML_WAN_IFACE_LCP_STATUS LCPStatus; + DML_WAN_IFACE_PPP_LINK_STATUS LinkStatus; + DML_WAN_IFACE_LINK_TYPE LinkType; +} DATAMODEL_PPP; + +typedef struct _DML_WANIFACE_WANCFG_VALID +{ + BOOL DiscoverOffer; + BOOL SolicitAdvertise; + BOOL RS_RA; + BOOL PadiPado; +} DML_WANIFACE_WANCFG_VALID; + +typedef struct _DML_WANIFACE_INFO +{ + CHAR Name[BUFLEN_64]; + BOOL Enable; + INT Priority; + DML_WAN_IFACE_TYPE Type; + UINT SelectionTimeout; + BOOL EnableMAPT; + BOOL EnableDSLite; + BOOL EnableIPoE; + BOOL ActiveLink; + DML_WAN_IFACE_STATUS Status; + DML_WAN_IFACE_LINKSTATUS LinkStatus; + BOOL Refresh; + DML_WANIFACE_WANCFG_VALID Validation; +} DML_WANIFACE_INFO; + +typedef struct _DML_WANIFACE_DYNTRIGGER +{ + BOOL Enable; + ULONG Delay; +} DML_WANIFACE_DYNTRIGGER; + + +typedef struct _WANMGR_IPV4_DATA +{ + char ifname[BUFLEN_64]; + char ip[BUFLEN_32]; /** New IP address, if addressAssigned==TRUE */ + char mask[BUFLEN_32]; /** New netmask, if addressAssigned==TRUE */ + char gateway[BUFLEN_32]; /** New gateway, if addressAssigned==TRUE */ + char dnsServer[BUFLEN_64]; /** New dns Server, if addressAssigned==TRUE */ + char dnsServer1[BUFLEN_64]; /** New dns Server, if addressAssigned==TRUE */ +} WANMGR_IPV4_DATA; + + +typedef struct _WANMGR_IPV6_DATA +{ + char ifname[BUFLEN_32]; + char address[BUFLEN_48]; /**< New IPv6 address, if addrAssigned==TRUE */ + char pdIfAddress[BUFLEN_48]; /**< New IPv6 address of PD interface */ + char nameserver[BUFLEN_128]; /**< New nameserver, if addressAssigned==TRUE */ + char nameserver1[BUFLEN_128]; /**< New nameserver, if addressAssigned==TRUE */ + char domainName[BUFLEN_64]; /**< New domain Name, if addressAssigned==TRUE */ + char sitePrefix[BUFLEN_48]; /**< New site prefix, if prefixAssigned==TRUE */ + uint32_t prefixPltime; + uint32_t prefixVltime; + char sitePrefixOld[BUFLEN_48]; /**< add support for RFC7084 requirement L-13 */ +} WANMGR_IPV6_DATA; + + +typedef struct _DML_WANIFACE_IP +{ + CHAR Path[BUFLEN_64]; + DML_WAN_IFACE_IPV4_STATUS Ipv4Status; + DML_WAN_IFACE_IPV6_STATUS Ipv6Status; + BOOL Ipv4Changed; + BOOL Ipv6Changed; + WANMGR_IPV4_DATA Ipv4Data; + WANMGR_IPV6_DATA Ipv6Data; + ipc_dhcpv4_data_t* pIpcIpv4Data; + ipc_dhcpv6_data_t* pIpcIpv6Data; + UINT Dhcp4cPid; + UINT Dhcp6cPid; +} DML_WANIFACE_IP; + + +typedef struct _DML_WANIFACE_MAP +{ + DML_WAN_IFACE_MAPT_STATUS MaptStatus; + CHAR Path[BUFLEN_64]; + BOOL MaptChanged; +#ifdef FEATURE_MAPT + Dhcp6cMAPTParametersMsgBody dhcp6cMAPTparameters; +#endif +} DML_WANIFACE_MAP; + +typedef struct _DML_WANIFACE_DSLITE +{ + CHAR Path[BUFLEN_64]; + DML_WAN_IFACE_DSLITE_STATUS Status; + BOOL Changed; +} DML_WANIFACE_DSLITE; + +typedef struct _DML_WAN_INTERFACE +{ + UINT uiIfaceIdx; + UINT uiInstanceNumber; + CHAR Name[BUFLEN_64]; + CHAR DisplayName[BUFLEN_64]; + DML_WANIFACE_PHY Phy; + DML_WANIFACE_INFO Wan; + DML_WANIFACE_DYNTRIGGER DynamicTrigger; + DML_WANIFACE_IP IP; + DATAMODEL_PPP PPP; + DML_WANIFACE_MAP MAP; + DML_WANIFACE_DSLITE DSLite; + DATAMODEL_MARKING Marking; +} DML_WAN_IFACE; + + +/*** RDK WAN Manager ***/ +typedef struct _DML_WANMGR_CONFIG_ +{ + BOOLEAN Enable; + DML_WAN_POLICY Policy; + UINT IdleTimeout; +} DML_WANMGR_CONFIG; + +#endif //_WANMGR_DML_H_ diff --git a/source/TR-181/middle_layer_src/Makefile.am b/source/TR-181/middle_layer_src/Makefile.am new file mode 100644 index 00000000..79be0c64 --- /dev/null +++ b/source/TR-181/middle_layer_src/Makefile.am @@ -0,0 +1,33 @@ +########################################################################## +# If not stated otherwise in this file or this component's Licenses.txt +# file the following copyright and licenses apply: +# +# Copyright 2015 RDK Management +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +########################################################################## + +AM_CFLAGS = -D_ANSC_LINUX +AM_CFLAGS += -D_ANSC_USER +AM_CFLAGS += -D_ANSC_LITTLE_ENDIAN_ +AM_LDFLAGS = -lccsp_common +AM_LDFLAGS += -lcm_mgnt + +AM_CPPFLAGS = -Wall -Werror +ACLOCAL_AMFLAGS = -I m4 +hardware_platform = i686-linux-gnu + +noinst_LTLIBRARIES = libCcspWanManager_middle_layer_src.la +libCcspWanManager_middle_layer_src_la_CPPFLAGS = -I/var/tmp/pc-rdkb/include/dbus-1.0 -I$(top_srcdir)/../CcspCommonLibrary/source/ccsp/custom -I$(top_srcdir)/../CcspCommonLibrary/source/ccsp/include -I$(top_srcdir)/../CcspCommonLibrary/source/debug_api/include -I$(top_srcdir)/../CcspCommonLibrary/source/cosa/include -I$(top_srcdir)/../CcspCommonLibrary/source/cosa/include/linux -I$(top_srcdir)/../CcspCommonLibrary/source/ccsp/components/include -I$(top_srcdir)/../CcspCommonLibrary/source/cosa/package/slap/include -I$(top_srcdir)/../hal/include -I$(top_srcdir)/source/TR-181/board_sbapi -I$(top_srcdir)/../CcspCommonLibrary/source/util_api/http/include -I$(top_srcdir)/../CcspCommonLibrary/source/util_api/ansc/include -I$(top_srcdir)/source/TR-181/middle_layer_src -I$(top_srcdir)/../CcspCommonLibrary/source/ccsp/components/common/MessageBusHelper/include -I$(top_srcdir)/source/TR-181/include -I$(top_srcdir)/source/WanManager -I${PKG_CONFIG_SYSROOT_DIR}$(includedir) $(CPPFLAGS) +libCcspWanManager_middle_layer_src_la_SOURCES = wanmgr_plugin_main.c wanmgr_plugin_main_apis.c wanmgr_dml_apis.c wanmgr_dml_iface_apis.c wanmgr_rdkbus_utils.c wanmgr_rdkbus_apis.c wanmgr_dml_dhcpv4.c wanmgr_dml_dhcpv6.c +libCcspWanManager_middle_layer_src_la_LDFLAGS = -lccsp_common -lsyscfg -lsysevent -lpthread diff --git a/source/TR-181/middle_layer_src/wanmgr_bus_utils.h b/source/TR-181/middle_layer_src/wanmgr_bus_utils.h new file mode 100644 index 00000000..9dc92d9c --- /dev/null +++ b/source/TR-181/middle_layer_src/wanmgr_bus_utils.h @@ -0,0 +1,86 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2015 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +/********************************************************************** + Copyright [2014] [Cisco Systems, Inc.] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +**********************************************************************/ + +/********************************************************************** + + module: dslh_dmagnt_exported.c + + For DSL Home Model Implementation (DSLH), + BroadWay Service Delivery System + + --------------------------------------------------------------- + + description: + + This module implements the framework's exported functions + by the Dslh DataModelAgent object; + + * GetParamValueUlong2 + * GetParamValueString + * GetParamValueBool + * GetInstanceNumberByIndex + + --------------------------------------------------------------- + + environment: + + platform independent + + --------------------------------------------------------------- + + author: + + Bin Zhu + + --------------------------------------------------------------- + + revision: + + 01/06/2011 initial revision. + 01/11/2011 added SLAP related apis. + 03/21/2011 added api to retrieve instance number by index + +**********************************************************************/ +#ifndef _WANMGR_BUS_UTILS_H_ +#define _WANMGR_BUS_UTILS_H_ + + +ULONG GetParamValueUlong (char* pParamName); +int GetParamValueString (char* pParamName, char* pBuffer, PULONG pulSize); +BOOL GetParamValueBool (char* pParamName); +ULONG GetInstanceNumberByIndex (char* pObjName, ULONG ulIndex); + + +#endif //_WANMGR_BUS_UTILS_H_ diff --git a/source/TR-181/middle_layer_src/wanmgr_dml_apis.c b/source/TR-181/middle_layer_src/wanmgr_dml_apis.c new file mode 100644 index 00000000..d3cc0a11 --- /dev/null +++ b/source/TR-181/middle_layer_src/wanmgr_dml_apis.c @@ -0,0 +1,161 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2017 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + + +/********************************************************************** + Copyright [2014] [Cisco Systems, Inc.] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +**********************************************************************/ + +#include "wanmgr_dml_apis.h" + +#include "wanmgr_data.h" +#include "wanmgr_controller.h" +#include "wanmgr_rdkbus_utils.h" + + +BOOL +WanManager_GetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG* puLong) +{ + BOOL ret = FALSE; + + WanMgr_Config_Data_t* pWanConfigData = WanMgr_GetConfigData_locked(); + if(pWanConfigData != NULL) + { + DML_WANMGR_CONFIG* pWanDmlData = &(pWanConfigData->data); + + if(AnscEqualString(ParamName, "Policy", TRUE)) + { + *puLong= pWanDmlData->Policy; + ret = TRUE; + } + else if(AnscEqualString(ParamName, "IdleTimeout", TRUE)) + { + *puLong= pWanDmlData->IdleTimeout; + ret = TRUE; + } + + WanMgrDml_GetConfigData_release(pWanConfigData); + } + + return ret; +} + +BOOL +WanManager_SetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG uValue) +{ + BOOL ret = FALSE; + ANSC_STATUS retStatus; + + WanMgr_Config_Data_t* pWanConfigData = WanMgr_GetConfigData_locked(); + if(pWanConfigData != NULL) + { + DML_WANMGR_CONFIG* pWanDmlData = &(pWanConfigData->data); + + if(AnscEqualString(ParamName, "Policy", TRUE)) + { + retStatus = WanMgr_RdkBus_setWanPolicy((DML_WAN_POLICY)uValue); + if(retStatus == ANSC_STATUS_SUCCESS) + { + pWanDmlData->Policy = uValue; + WanController_Policy_Change(); + ret = TRUE; + } + } + else if(AnscEqualString(ParamName, "IdleTimeout", TRUE)) + { + pWanDmlData->IdleTimeout = uValue; + ret = TRUE; + } + + WanMgrDml_GetConfigData_release(pWanConfigData); + } + + return ret; +} + +BOOL +WanManager_GetParamBoolValue(ANSC_HANDLE hInsContext, char* ParamName, BOOL* pBool) +{ + BOOL ret = FALSE; + + WanMgr_Config_Data_t* pWanConfigData = WanMgr_GetConfigData_locked(); + if(pWanConfigData != NULL) + { + DML_WANMGR_CONFIG* pWanDmlData = &(pWanConfigData->data); + if(AnscEqualString(ParamName, "Enable", TRUE)) + { + *pBool= pWanDmlData->Enable; + ret = TRUE; + } + + WanMgrDml_GetConfigData_release(pWanConfigData); + } + + return ret; +} + +ULONG WanManager_GetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pValue, ULONG* pulSize) +{ + return -1; //Not supported parameter. +} + +BOOL WanManager_SetParamBoolValue(ANSC_HANDLE hInsContext, char* ParamName, BOOL bValue) +{ + BOOL ret = FALSE; + + WanMgr_Config_Data_t* pWanConfigData = WanMgr_GetConfigData_locked(); + if(pWanConfigData != NULL) + { + DML_WANMGR_CONFIG* pWanDmlData = &(pWanConfigData->data); + + + if(AnscEqualString(ParamName, "Enable", TRUE)) + { + pWanDmlData->Enable = bValue; + ret = TRUE; + } + + WanMgrDml_GetConfigData_release(pWanConfigData); + } + + return ret; +} +ULONG WanManager_Validate(ANSC_HANDLE hInsContext) +{ + return TRUE; +} + +ULONG WanManager_Commit(ANSC_HANDLE hInsContext) +{ + ULONG ret = -1; + + return ret; +} diff --git a/source/TR-181/middle_layer_src/wanmgr_dml_apis.h b/source/TR-181/middle_layer_src/wanmgr_dml_apis.h new file mode 100644 index 00000000..f4becdea --- /dev/null +++ b/source/TR-181/middle_layer_src/wanmgr_dml_apis.h @@ -0,0 +1,61 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2017 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +/********************************************************************** + Copyright [2014] [Cisco Systems, Inc.] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +**********************************************************************/ +#ifndef _WANMGR_DML_APIS_H_ +#define _WANMGR_DML_APIS_H_ + +#include "ansc_platform.h" + +/*********************************************************************** + + APIs for Object: + + InternetGatewayDevice.X_CISCO_COM_COSADataModel.PluginSampleObj. + + * PluginSampleObj_GetBulkParamValues + * PluginSampleObj_SetBulkParamValues + * PluginSampleObj_Validate + * PluginSampleObj_Commit + * PluginSampleObj_Rollback + +***********************************************************************/ +BOOL WanManager_GetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG* puLong); +BOOL WanManager_SetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG uValue); +ULONG WanManager_Commit(ANSC_HANDLE hInsContext); +BOOL WanManager_SetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pString); +ULONG WanManager_GetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pValue, ULONG* pUlSize); +BOOL WanManager_GetParamBoolValue(ANSC_HANDLE hInsContext, char* ParamName, BOOL* pBool); +BOOL WanManager_SetParamBoolValue(ANSC_HANDLE hInsContext, char* ParamName, BOOL bValue); + +#endif //_WANMGR_DML_APIS_H_ diff --git a/source/TR-181/middle_layer_src/wanmgr_dml_dhcpv4.c b/source/TR-181/middle_layer_src/wanmgr_dml_dhcpv4.c new file mode 100644 index 00000000..ed0c3d07 --- /dev/null +++ b/source/TR-181/middle_layer_src/wanmgr_dml_dhcpv4.c @@ -0,0 +1,3373 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2015 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +/********************************************************************** + Copyright [2014] [Cisco Systems, Inc.] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +**********************************************************************/ + +#include "ansc_platform.h" +#include "wanmgr_dml_dhcpv4.h" +#include "wanmgr_dhcpv4_apis.h" +#include "wanmgr_dhcpv4_internal.h" +#include "wanmgr_plugin_main_apis.h" + +#include "ccsp_base_api.h" +#include "messagebus_interface_helper.h" + +extern WANMGR_BACKEND_OBJ* g_pWanMgrBE; +extern void* g_pDslhDmlAgent; + +extern ULONG g_currentBsUpdate; +extern char * getRequestorString(); +extern char * getTime(); + +#define BS_SOURCE_WEBPA_STR "webpa" +#define BS_SOURCE_RFC_STR "rfc" +#define PARTNER_ID_LEN 64 + +#define DATAMODEL_PARAM_LENGTH 256 + + +/*********************************************************************** + IMPORTANT NOTE: + + According to TR69 spec: + On successful receipt of a SetParameterValues RPC, the CPE MUST apply + the changes to all of the specified Parameters atomically. That is, either + all of the value changes are applied together, or none of the changes are + applied at all. In the latter case, the CPE MUST return a fault response + indicating the reason for the failure to apply the changes. + + The CPE MUST NOT apply any of the specified changes without applying all + of them. + + In order to set parameter values correctly, the back-end is required to + hold the updated values until "Validate" and "Commit" are called. Only after + all the "Validate" passed in different objects, the "Commit" will be called. + Otherwise, "Rollback" will be called instead. + + The sequence in COSA Data Model will be: + + SetParamBoolValue/SetParamIntValue/SetParamUlongValue/SetParamStringValue + -- Backup the updated values; + + if( Validate_XXX()) + { + Commit_XXX(); -- Commit the update all together in the same object + } + else + { + Rollback_XXX(); -- Remove the update at backup; + } + +***********************************************************************/ +/*********************************************************************** + + APIs for Object: + + DHCPv4. + + * DHCPv4_GetParamBoolValue + * DHCPv4_GetParamIntValue + * DHCPv4_GetParamUlongValue + * DHCPv4_GetParamStringValue + +***********************************************************************/ +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + DHCPv4_GetParamBoolValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + BOOL* pBool + ); + + description: + + This function is called to retrieve Boolean parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + BOOL* pBool + The buffer of returned boolean value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +DHCPv4_GetParamBoolValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + BOOL* pBool + ) +{ + UNREFERENCED_PARAMETER(hInsContext); + UNREFERENCED_PARAMETER(ParamName); + UNREFERENCED_PARAMETER(pBool); + /* check the parameter name and return the corresponding value */ + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + DHCPv4_GetParamIntValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + int* pInt + ); + + description: + + This function is called to retrieve integer parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + int* pInt + The buffer of returned integer value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +DHCPv4_GetParamIntValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + int* pInt + ) +{ + UNREFERENCED_PARAMETER(hInsContext); + UNREFERENCED_PARAMETER(ParamName); + UNREFERENCED_PARAMETER(pInt); + /* check the parameter name and return the corresponding value */ + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + DHCPv4_GetParamUlongValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + ULONG* puLong + ); + + description: + + This function is called to retrieve ULONG parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + ULONG* puLong + The buffer of returned ULONG value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +DHCPv4_GetParamUlongValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + ULONG* puLong + ) +{ + UNREFERENCED_PARAMETER(hInsContext); + UNREFERENCED_PARAMETER(ParamName); + UNREFERENCED_PARAMETER(puLong); + /* check the parameter name and return the corresponding value */ + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG + DHCPv4_GetParamStringValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + char* pValue, + ULONG* pUlSize + ); + + description: + + This function is called to retrieve string parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + char* pValue, + The string value buffer; + + ULONG* pUlSize + The buffer of length of string value; + Usually size of 1023 will be used. + If it's not big enough, put required size here and return 1; + + return: 0 if succeeded; + 1 if short of buffer size; (*pUlSize = required size) + -1 if not supported. + +**********************************************************************/ +ULONG +DHCPv4_GetParamStringValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + char* pValue, + ULONG* pUlSize + ) +{ + UNREFERENCED_PARAMETER(hInsContext); + UNREFERENCED_PARAMETER(ParamName); + UNREFERENCED_PARAMETER(pValue); + UNREFERENCED_PARAMETER(pUlSize); + + /* check the parameter name and return the corresponding value */ + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return -1; +} + +/*********************************************************************** + + APIs for Object: + + DHCPv4.Client.{i}. + + * Client_GetEntryCount + * Client_GetEntry + * Client_AddEntry + * Client_DelEntry + * Client_GetParamBoolValue + * Client_GetParamIntValue + * Client_GetParamUlongValue + * Client_GetParamStringValue + * Client_SetParamBoolValue + * Client_SetParamIntValue + * Client_SetParamUlongValue + * Client_SetParamStringValue + * Client_Validate + * Client_Commit + * Client_Rollback + +***********************************************************************/ +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG + Client_GetEntryCount + ( + ANSC_HANDLE hInsContext + ); + + description: + + This function is called to retrieve the count of the table. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: The count of the table + +**********************************************************************/ +ULONG +Client_GetEntryCount + ( + ANSC_HANDLE hInsContext + ) +{ + UNREFERENCED_PARAMETER(hInsContext); + ULONG ClientCount = 0; + PWAN_DHCPV4_DATA pDhcpv4 = (PWAN_DHCPV4_DATA)g_pWanMgrBE->hDhcpv4; + + if (pDhcpv4 != NULL) + { + ClientCount = AnscSListQueryDepth( &pDhcpv4->ClientList ); + } + return ClientCount; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ANSC_HANDLE + Client_GetEntry + ( + ANSC_HANDLE hInsContext, + ULONG nIndex, + ULONG* pInsNumber + ); + + description: + + This function is called to retrieve the entry specified by the index. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + ULONG nIndex, + The index of this entry; + + ULONG* pInsNumber + The output instance number; + + return: The handle to identify the entry + +**********************************************************************/ +ANSC_HANDLE +Client_GetEntry + ( + ANSC_HANDLE hInsContext, + ULONG nIndex, + ULONG* pInsNumber + ) +{ + PSINGLE_LINK_ENTRY pSListEntry = NULL; + PWAN_DHCPV4_DATA pDhcpv4 = (PWAN_DHCPV4_DATA)g_pWanMgrBE->hDhcpv4; + PDHCPC_CONTEXT_LINK_OBJECT pCxtLink = NULL; + + UNREFERENCED_PARAMETER(hInsContext); + + if (pDhcpv4 != NULL) + { + pSListEntry = AnscSListGetEntryByIndex(&pDhcpv4->ClientList, nIndex); + + if ( pSListEntry ) + { + pCxtLink = ACCESS_CONTEXT_DHCPC_LINK_OBJECT(pSListEntry); + *pInsNumber = pCxtLink->InstanceNumber; + } + } + + return pSListEntry; + +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ANSC_HANDLE + Client_AddEntry + ( + ANSC_HANDLE hInsContext, + ULONG* pInsNumber + ); + + description: + + This function is called to add a new entry. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + ULONG* pInsNumber + The output instance number; + + return: The handle of new added entry. + +**********************************************************************/ +ANSC_HANDLE +Client_AddEntry + ( + ANSC_HANDLE hInsContext, + ULONG* pInsNumber + ) +{ + UNREFERENCED_PARAMETER(hInsContext); + return WanMgr_DmlDhcpcAddEntry(hInsContext, *pInsNumber); + +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG + Client_DelEntry + ( + ANSC_HANDLE hInsContext, + ANSC_HANDLE hInstance + ); + + description: + + This function is called to delete an exist entry. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + ANSC_HANDLE hInstance + The exist entry handle; + + return: The status of the operation. + +**********************************************************************/ +ULONG +Client_DelEntry + ( + ANSC_HANDLE hInsContext, + ANSC_HANDLE hInstance + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PSINGLE_LINK_ENTRY pSListEntry = NULL; + PWAN_DHCPV4_DATA pDhcpv4 = (PWAN_DHCPV4_DATA)g_pWanMgrBE->hDhcpv4; + UNREFERENCED_PARAMETER(hInsContext); + + if (pDhcpv4 != NULL) + { + PDHCPC_CONTEXT_LINK_OBJECT pCxtLink = (PDHCPC_CONTEXT_LINK_OBJECT)hInstance; + PCONTEXT_LINK_OBJECT pCxtLink2 = NULL; + PDML_DHCPC_FULL pDhcpc = (PDML_DHCPC_FULL)pCxtLink->hContext; + + /* Normally, two sublinks are empty because our framework will firstly + call delEntry for them before coming here. We needn't care them. + */ + if ( !pCxtLink->bNew ) + { + returnStatus = WanMgr_DmlDhcpcDelEntry(NULL, pDhcpc->Cfg.InstanceNumber); + if ( returnStatus != ANSC_STATUS_SUCCESS ) + { + return returnStatus; + } + } + + if (AnscSListPopEntryByLink(&pDhcpv4->ClientList, &pCxtLink->Linkage) ) + { + /* Because the current NextInstanceNumber information need be deleted */ + WanMgr_Dhcpv4RegSetDhcpv4Info(pDhcpv4); + + AnscFreeMemory(pCxtLink->hContext); + AnscFreeMemory(pCxtLink); + } + } + + return returnStatus; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + Client_GetParamBoolValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + BOOL* pBool + ); + + description: + + This function is called to retrieve Boolean parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + BOOL* pBool + The buffer of returned boolean value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +Client_GetParamBoolValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + BOOL* pBool + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PDHCPC_CONTEXT_LINK_OBJECT pCxtLink = (PDHCPC_CONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPC_FULL pDhcpc = (PDML_DHCPC_FULL)pCxtLink->hContext; + + /* check the parameter name and return the corresponding value */ + if( AnscEqualString(ParamName, "Enable", TRUE)) + { + /* collect value */ + *pBool = pDhcpc->Cfg.bEnabled; + + return TRUE; + } + + else if( AnscEqualString(ParamName, "Renew", TRUE)) + { + /* collect value */ + *pBool = FALSE; + + return TRUE; + } + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + Client_GetParamIntValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + int* pInt + ); + + description: + + This function is called to retrieve integer parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + int* pInt + The buffer of returned integer value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +Client_GetParamIntValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + int* pInt + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PDHCPC_CONTEXT_LINK_OBJECT pCxtLink = (PDHCPC_CONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPC_FULL pDhcpc = (PDML_DHCPC_FULL)pCxtLink->hContext; + + /* check the parameter name and return the corresponding value */ + if( AnscEqualString(ParamName, "LeaseTimeRemaining", TRUE)) + { + /* collect value */ + WanMgr_DmlDhcpcGetInfo(NULL, pCxtLink->InstanceNumber, &pDhcpc->Info); + + *pInt = pDhcpc->Info.LeaseTimeRemaining; + + return TRUE; + } + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + Client_GetParamUlongValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + ULONG* puLong + ); + + description: + + This function is called to retrieve ULONG parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + ULONG* puLong + The buffer of returned ULONG value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +Client_GetParamUlongValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + ULONG* puLong + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PDHCPC_CONTEXT_LINK_OBJECT pCxtLink = (PDHCPC_CONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPC_FULL pDhcpc = (PDML_DHCPC_FULL)pCxtLink->hContext; + + + /* check the parameter name and return the corresponding value */ + if( AnscEqualString(ParamName, "Status", TRUE)) + { + /* collect value */ + WanMgr_DmlDhcpcGetInfo(NULL, pCxtLink->InstanceNumber, &pDhcpc->Info); + + *puLong = pDhcpc->Info.Status; + + return TRUE; + } + + else if( AnscEqualString(ParamName, "DHCPStatus", TRUE)) + { + /* collect value */ + WanMgr_DmlDhcpcGetInfo(NULL, pCxtLink->InstanceNumber, &pDhcpc->Info); + + *puLong = pDhcpc->Info.DHCPStatus; + + return TRUE; + } + + else if( AnscEqualString(ParamName, "IPAddress", TRUE)) + { + /* collect value */ + WanMgr_DmlDhcpcGetInfo(NULL, pCxtLink->InstanceNumber, &pDhcpc->Info); + if ( pDhcpc->Info.DHCPStatus == DML_DHCPC_STATUS_Bound ) + { + *puLong = pDhcpc->Info.IPAddress.Value; + } + else + { + *puLong = 0; + } + + + return TRUE; + } + + else if( AnscEqualString(ParamName, "SubnetMask", TRUE)) + { + /* collect value */ + WanMgr_DmlDhcpcGetInfo(NULL, pCxtLink->InstanceNumber, &pDhcpc->Info); + if ( pDhcpc->Info.DHCPStatus == DML_DHCPC_STATUS_Bound ) + { + *puLong = pDhcpc->Info.SubnetMask.Value; + } + else + { + *puLong = 0; + } + + return TRUE; + } + + else if( AnscEqualString(ParamName, "DHCPServer", TRUE)) + { + /* collect value */ + if ( !pDhcpc->Info.DHCPServer.Value ) + { + WanMgr_DmlDhcpcGetInfo(NULL, pCxtLink->InstanceNumber, &pDhcpc->Info); + } + + *puLong = pDhcpc->Info.DHCPServer.Value; + + return TRUE; + } + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG + Client_GetParamStringValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + char* pValue, + ULONG* pUlSize + ); + + description: + + This function is called to retrieve string parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + char* pValue, + The string value buffer; + + ULONG* pUlSize + The buffer of length of string value; + Usually size of 1023 will be used. + If it's not big enough, put required size here and return 1; + + return: 0 if succeeded; + 1 if short of buffer size; (*pUlSize = required size) + -1 if not supported. + +**********************************************************************/ +ULONG +Client_GetParamStringValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + char* pValue, + ULONG* pUlSize + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PDHCPC_CONTEXT_LINK_OBJECT pCxtLink = (PDHCPC_CONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPC_FULL pDhcpc = (PDML_DHCPC_FULL)pCxtLink->hContext; + + ULONG i, len = 0; + INT instanceNumber = -1; + CHAR tmpBuff[DATAMODEL_PARAM_LENGTH] = {0}; + CHAR interface[DATAMODEL_PARAM_LENGTH] = {0}; + + /* check the parameter name and return the corresponding value */ + if( AnscEqualString(ParamName, "Alias", TRUE)) + { + /* collect value */ + if ( AnscSizeOfString(pDhcpc->Cfg.Alias) < *pUlSize) + { + AnscCopyString(pValue, pDhcpc->Cfg.Alias); + return 0; + } + else + { + *pUlSize = AnscSizeOfString(pDhcpc->Cfg.Alias)+1; + return 1; + } + } + + else if( AnscEqualString(ParamName, "X_CISCO_COM_BootFileName", TRUE)) + { + /* collect value */ + if ( AnscSizeOfString(pDhcpc->Cfg.X_CISCO_COM_BootFileName) < *pUlSize) + { + AnscCopyString(pValue, pDhcpc->Cfg.X_CISCO_COM_BootFileName); + return 0; + } + else + { + *pUlSize = AnscSizeOfString(pDhcpc->Cfg.X_CISCO_COM_BootFileName)+1; + return 1; + } + } + + else if( AnscEqualString(ParamName, "Interface", TRUE)) + { + DmlGetInstanceByKeywordFromPandM(pDhcpc->Cfg.Interface, &instanceNumber); + snprintf(interface, DATAMODEL_PARAM_LENGTH, PAM_IF_TABLE_OBJECT, instanceNumber); + + if ( interface[0] != '\0' ) + { + if ( AnscSizeOfString(interface) < *pUlSize) + { + AnscCopyString(pValue, interface); + return 0; + } + else + { + *pUlSize = AnscSizeOfString(interface)+1; + + return 1; + } + } + else + { + return 0; + } + + } + + else if( AnscEqualString(ParamName, "IPRouters", TRUE)) + { + /* collect value */ + WanMgr_DmlDhcpcGetInfo(NULL, pCxtLink->InstanceNumber, &pDhcpc->Info); + if ( pDhcpc->Info.DHCPStatus != DML_DHCPC_STATUS_Bound ) + { + *pValue = '\0'; + return 0; + } + + AnscZeroMemory(tmpBuff, sizeof(tmpBuff)); + for( i=0; iInfo.NumIPRouters && i 0) + tmpBuff[len++] = ','; + + AnscCopyString( &tmpBuff[len], _ansc_inet_ntoa(*((struct in_addr *)(&pDhcpc->Info.IPRouters[i]))) ); + } + + if ( AnscSizeOfString(tmpBuff) < *pUlSize) + { + AnscCopyString(pValue, tmpBuff); + return 0; + } + else + { + *pUlSize = AnscSizeOfString(pDhcpc->Cfg.Interface)+1; + return 1; + } + + return 0; + } + + else if( AnscEqualString(ParamName, "DNSServers", TRUE)) + { + /* collect value */ + + if ( pDhcpc->Info.DHCPStatus == DML_DHCPC_STATUS_Bound ) + { + WanMgr_DmlDhcpcGetInfo(NULL, pCxtLink->InstanceNumber, &pDhcpc->Info); + } + else + { + *pValue = '\0'; + return 0; + } + + AnscZeroMemory(tmpBuff, sizeof(tmpBuff)); + for( i=0; iInfo.NumDnsServers && i 0) + tmpBuff[len++] = ','; + + AnscCopyString( &tmpBuff[len], _ansc_inet_ntoa(*((struct in_addr *)(&pDhcpc->Info.DNSServers[i]))) ); + } + + if ( AnscSizeOfString(tmpBuff) < *pUlSize) + { + AnscCopyString(pValue, tmpBuff); + return 0; + } + else + { + *pUlSize = AnscSizeOfString(pDhcpc->Cfg.Interface)+1; + return 1; + } + + return 0; + } + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return -1; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + Client_SetParamBoolValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + BOOL bValue + ); + + description: + + This function is called to set BOOL parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + BOOL bValue + The updated BOOL value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +Client_SetParamBoolValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + BOOL bValue + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PDHCPC_CONTEXT_LINK_OBJECT pCxtLink = (PDHCPC_CONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPC_FULL pDhcpc = (PDML_DHCPC_FULL)pCxtLink->hContext; + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "Enable", TRUE)) + { + /* save update to backup */ + pDhcpc->Cfg.bEnabled = bValue; + + return TRUE; + } + + else if( AnscEqualString(ParamName, "Renew", TRUE)) + { + /* save update to backup */ + if ( bValue ) + { + returnStatus = WanMgr_DmlDhcpcRenew(NULL, pDhcpc->Cfg.InstanceNumber); + if ( returnStatus != ANSC_STATUS_SUCCESS ) + { + return FALSE; + } + } + + return TRUE; + } + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + Client_SetParamIntValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + int iValue + ); + + description: + + This function is called to set integer parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + int iValue + The updated integer value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +Client_SetParamIntValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + int iValue + ) +{ + UNREFERENCED_PARAMETER(hInsContext); + UNREFERENCED_PARAMETER(ParamName); + UNREFERENCED_PARAMETER(iValue); + + /* check the parameter name and set the corresponding value */ + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + Client_SetParamUlongValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + ULONG uValue + ); + + description: + + This function is called to set ULONG parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + ULONG uValue + The updated ULONG value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +Client_SetParamUlongValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + ULONG uValue + ) +{ + UNREFERENCED_PARAMETER(hInsContext); + UNREFERENCED_PARAMETER(ParamName); + UNREFERENCED_PARAMETER(uValue); + + /* check the parameter name and set the corresponding value */ + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + Client_SetParamStringValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + char* pString + ); + + description: + + This function is called to set string parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + char* pString + The updated string value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +Client_SetParamStringValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + char* pString + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PWAN_DHCPV4_DATA pDhcpv4 = (PWAN_DHCPV4_DATA)g_pWanMgrBE->hDhcpv4; + PDHCPC_CONTEXT_LINK_OBJECT pCxtLink = (PDHCPC_CONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPC_FULL pDhcpc = (PDML_DHCPC_FULL)pCxtLink->hContext; + PSINGLE_LINK_ENTRY pSListEntry = NULL; + PDML_DHCPC_FULL pDhcpc2 = NULL; + BOOL bFound = FALSE; + + if (pDhcpv4 == NULL) + { + AnscTraceError(("%s:%d:: Pointer is null!!\n", __FUNCTION__, __LINE__)); + return ANSC_STATUS_FAILURE; + } + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "Alias", TRUE)) + { + AnscCopyString(pDhcpv4->AliasOfClient, pDhcpc->Cfg.Alias); + AnscCopyString(pDhcpc->Cfg.Alias, pString); + return TRUE; + } + else if( AnscEqualString(ParamName, "X_CISCO_COM_BootFileName", TRUE)) + { + AnscCopyString(pDhcpc->Cfg.X_CISCO_COM_BootFileName, pString); + + return TRUE; + } + + else if( AnscEqualString(ParamName, "Interface", TRUE)) + { + /* save update to backup */ + AnscCopyString(pDhcpc->Cfg.Interface, pString); + + return TRUE; + } + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + Client_Validate + ( + ANSC_HANDLE hInsContext, + char* pReturnParamName, + ULONG* puLength + ); + + description: + + This function is called to finally commit all the update. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* pReturnParamName, + The buffer (128 bytes) of parameter name if there's a validation. + + ULONG* puLength + The output length of the param name. + + return: TRUE if there's no validation. + +**********************************************************************/ +BOOL +Client_Validate + ( + ANSC_HANDLE hInsContext, + char* pReturnParamName, + ULONG* puLength + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PDHCPC_CONTEXT_LINK_OBJECT pCxtLink = (PDHCPC_CONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPC_FULL pDhcpc = (PDML_DHCPC_FULL)pCxtLink->hContext; + PSINGLE_LINK_ENTRY pSListEntry = NULL; + PDML_DHCPC_FULL pDhcpc2 = NULL; + BOOL bFound = FALSE; + + UNREFERENCED_PARAMETER(puLength); + + /* only for Alias */ + PWAN_DHCPV4_DATA pDhcpv4 = (PWAN_DHCPV4_DATA)g_pWanMgrBE->hDhcpv4; + if ( pDhcpv4 != NULL && pDhcpv4->AliasOfClient[0] ) + { + pSListEntry = AnscSListGetFirstEntry(&pDhcpv4->ClientList); + while( pSListEntry != NULL) + { + pCxtLink = ACCESS_CONTEXT_DHCPC_LINK_OBJECT(pSListEntry); + pSListEntry = AnscSListGetNextEntry(pSListEntry); + + pDhcpc2 = (PDML_DHCPC_FULL)pCxtLink->hContext; + + if( DHCPV4_CLIENT_ENTRY_MATCH2(pDhcpc2->Cfg.Alias, pDhcpc->Cfg.Alias) ) + { + if ( (ANSC_HANDLE)pCxtLink == hInsContext ) + { + continue; + } + + _ansc_strcpy(pReturnParamName, "Alias"); + + bFound = TRUE; + + break; + } + } + + if ( bFound ) + { +#if COSA_DHCPV4_ROLLBACK_TEST + Client_Rollback(hInsContext); +#endif + return FALSE; + } + } + + /* some other checking */ + + return TRUE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG + Client_Commit + ( + ANSC_HANDLE hInsContext + ); + + description: + + This function is called to finally commit all the update. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: The status of the operation. + +**********************************************************************/ +ULONG +Client_Commit + ( + ANSC_HANDLE hInsContext + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PDHCPC_CONTEXT_LINK_OBJECT pCxtLink = (PDHCPC_CONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPC_FULL pDhcpc = (PDML_DHCPC_FULL)pCxtLink->hContext; + PWAN_DHCPV4_DATA pDhcpv4 = (PWAN_DHCPV4_DATA)g_pWanMgrBE->hDhcpv4; + + if (pDhcpv4 != NULL) + { + if ( pCxtLink->bNew ) + { + pCxtLink->bNew = FALSE; + WanMgr_Dhcpv4RegSetDhcpv4Info(pDhcpv4); + } + else + { + returnStatus = WanMgr_DmlDhcpcSetCfg(NULL, &pDhcpc->Cfg); + + if ( returnStatus != ANSC_STATUS_SUCCESS) + { + WanMgr_DmlDhcpcGetCfg(NULL, &pDhcpc->Cfg); + } + } + + AnscZeroMemory( pDhcpv4->AliasOfClient, sizeof(pDhcpv4->AliasOfClient) ); + } + + return returnStatus; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG + Client_Rollback + ( + ANSC_HANDLE hInsContext + ); + + description: + + This function is called to roll back the update whenever there's a + validation found. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: The status of the operation. + +**********************************************************************/ +ULONG +Client_Rollback + ( + ANSC_HANDLE hInsContext + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PDHCPC_CONTEXT_LINK_OBJECT pCxtLink = (PDHCPC_CONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPC_FULL pDhcpc = (PDML_DHCPC_FULL)pCxtLink->hContext; + PWAN_DHCPV4_DATA pDhcpv4 = (PWAN_DHCPV4_DATA)g_pWanMgrBE->hDhcpv4; + + if (pDhcpv4 != NULL) + { + if ( pDhcpv4->AliasOfClient[0] ) + AnscCopyString( pDhcpc->Cfg.Alias, pDhcpv4->AliasOfClient ); + + if ( !pCxtLink->bNew ) + { + WanMgr_DmlDhcpcGetCfg( NULL, &pDhcpc->Cfg ); + } + else + { + DHCPV4_CLIENT_SET_DEFAULTVALUE(pDhcpc); + } + + AnscZeroMemory( pDhcpv4->AliasOfClient, sizeof(pDhcpv4->AliasOfClient) ); + } + + return returnStatus; +} + +/*********************************************************************** + + APIs for Object: + + DHCPv4.Client.{i}.SentOption.{i}. + + * SentOption_GetEntryCount + * SentOption_GetEntry + * SentOption_AddEntry + * SentOption_DelEntry + * SentOption_GetParamBoolValue + * SentOption_GetParamIntValue + * SentOption_GetParamUlongValue + * SentOption_GetParamStringValue + * SentOption_SetParamBoolValue + * SentOption_SetParamIntValue + * SentOption_SetParamUlongValue + * SentOption_SetParamStringValue + * SentOption_Validate + * SentOption_Commit + * SentOption_Rollback + +***********************************************************************/ +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG + SentOption_GetEntryCount + ( + ANSC_HANDLE hInsContext + ); + + description: + + This function is called to retrieve the count of the table. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: The count of the table + +**********************************************************************/ +ULONG +SentOption_GetEntryCount + ( + ANSC_HANDLE hInsContext + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PDHCPC_CONTEXT_LINK_OBJECT pCxtLink = (PDHCPC_CONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPC_FULL pDhcpc = (PDML_DHCPC_FULL)pCxtLink->hContext; + + return AnscSListQueryDepth( &pCxtLink->SendOptionList ); +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG + SentOption_GetEntryStatus + ( + ANSC_HANDLE hInsContext + ); + + description: + + This function is called to retrieve the count of the table. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: The count of the table + +**********************************************************************/ +BOOL +SentOption_GetEntryStatus + ( + ANSC_HANDLE hInsContext, + PCHAR StatusName + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PDHCPC_CONTEXT_LINK_OBJECT pCxtLink = (PDHCPC_CONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPC_FULL pDhcpc = (PDML_DHCPC_FULL)pCxtLink->hContext; + + if( AnscEqualString(StatusName, "Committed", TRUE)) + { + /* collect value */ + if ( pCxtLink->bNew ) + return FALSE; + + } + + return TRUE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ANSC_HANDLE + SentOption_GetEntry + ( + ANSC_HANDLE hInsContext, + ULONG nIndex, + ULONG* pInsNumber + ); + + description: + + This function is called to retrieve the entry specified by the index. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + ULONG nIndex, + The index of this entry; + + ULONG* pInsNumber + The output instance number; + + return: The handle to identify the entry + +**********************************************************************/ +ANSC_HANDLE +SentOption_GetEntry + ( + ANSC_HANDLE hInsContext, + ULONG nIndex, + ULONG* pInsNumber + ) +{ + PDHCPC_CONTEXT_LINK_OBJECT pCxtDhcpcLink = (PDHCPC_CONTEXT_LINK_OBJECT)hInsContext; + PCONTEXT_LINK_OBJECT pCxtLink = NULL; + PSINGLE_LINK_ENTRY pSListEntry = NULL; + + pSListEntry = AnscSListGetEntryByIndex(&pCxtDhcpcLink->SendOptionList, nIndex); + + if ( pSListEntry ) + { + pCxtLink = ACCESS_CONTEXT_LINK_OBJECT(pSListEntry); + *pInsNumber = pCxtLink->InstanceNumber; + } + + return pSListEntry; + +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ANSC_HANDLE + SentOption_AddEntry + ( + ANSC_HANDLE hInsContext, + ULONG* pInsNumber + ); + + description: + + This function is called to add a new entry. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + ULONG* pInsNumber + The output instance number; + + return: The handle of new added entry. + +**********************************************************************/ +ANSC_HANDLE +SentOption_AddEntry + ( + ANSC_HANDLE hInsContext, + ULONG* pInsNumber + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PDHCPC_CONTEXT_LINK_OBJECT pCxtDhcpcLink = (PDHCPC_CONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPC_FULL pDhcpc = (PDML_DHCPC_FULL)pCxtDhcpcLink->hContext; + PCONTEXT_LINK_OBJECT pCxtLink = NULL; + PCOSA_DML_DHCP_OPT pDhcpSendOption = NULL; + + pDhcpSendOption = (PCOSA_DML_DHCP_OPT)AnscAllocateMemory( sizeof(COSA_DML_DHCP_OPT) ); + if ( !pDhcpSendOption ) + { + goto EXIT2; + } + + DHCPV4_SENDOPTION_SET_DEFAULTVALUE(pDhcpSendOption); + + pCxtLink = (PCONTEXT_LINK_OBJECT)AnscAllocateMemory( sizeof(CONTEXT_LINK_OBJECT) ); + if ( !pCxtLink ) + { + goto EXIT1; + } + + pCxtLink->hContext = (ANSC_HANDLE)pDhcpSendOption; + pCxtLink->hParentTable = (ANSC_HANDLE)pCxtDhcpcLink; + pCxtLink->bNew = TRUE; + + if ( !++pCxtDhcpcLink->maxInstanceOfSend ) + { + pCxtDhcpcLink->maxInstanceOfSend = 1; + } + + pDhcpSendOption->InstanceNumber = pCxtDhcpcLink->maxInstanceOfSend; + pCxtLink->InstanceNumber = pDhcpSendOption->InstanceNumber; + *pInsNumber = pDhcpSendOption->InstanceNumber; + + _ansc_sprintf( pDhcpSendOption->Alias, "SentOption%d", pDhcpSendOption->InstanceNumber); + + /* Put into our list */ + SListPushEntryByInsNum(&pCxtDhcpcLink->SendOptionList, (PCONTEXT_LINK_OBJECT)pCxtLink); + + /* we recreate the configuration */ + PWAN_DHCPV4_DATA pDhcpv4 = (PWAN_DHCPV4_DATA)g_pWanMgrBE->hDhcpv4; + if (pDhcpv4 != NULL) + { + WanMgr_Dhcpv4RegSetDhcpv4Info(pDhcpv4); + } + + return (ANSC_HANDLE)pCxtLink; + +EXIT1: + + AnscFreeMemory(pDhcpSendOption); + +EXIT2: + + return NULL; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG + SentOption_DelEntry + ( + ANSC_HANDLE hInsContext, + ANSC_HANDLE hInstance + ); + + description: + + This function is called to delete an exist entry. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + ANSC_HANDLE hInstance + The exist entry handle; + + return: The status of the operation. + +**********************************************************************/ +ULONG +SentOption_DelEntry + ( + ANSC_HANDLE hInsContext, + ANSC_HANDLE hInstance + ) +{ + UNREFERENCED_PARAMETER(hInsContext); + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PDHCPC_CONTEXT_LINK_OBJECT pCxtDhcpcLink = (PDHCPC_CONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPC_FULL pDhcpClient = (PDML_DHCPC_FULL)pCxtDhcpcLink->hContext; + PCONTEXT_LINK_OBJECT pCxtLink = (PCONTEXT_LINK_OBJECT)hInstance; + PCOSA_DML_DHCP_OPT pDhcpSendOption = (PCOSA_DML_DHCP_OPT)pCxtLink->hContext; + PWAN_DHCPV4_DATA pDhcpv4 = (PWAN_DHCPV4_DATA)g_pWanMgrBE->hDhcpv4; + + if (pDhcpv4 != NULL) + { + if ( !pCxtLink->bNew ) + { + returnStatus = WanMgr_DmlDhcpcDelSentOption(NULL, pDhcpClient->Cfg.InstanceNumber, pDhcpSendOption->InstanceNumber); + if ( returnStatus != ANSC_STATUS_SUCCESS ) + { + return returnStatus; + } + } + + if ( AnscSListPopEntryByLink(&pCxtDhcpcLink->SendOptionList, &pCxtLink->Linkage) ) + { + WanMgr_Dhcpv4RegSetDhcpv4Info(pDhcpv4); + + AnscFreeMemory(pCxtLink->hContext); + AnscFreeMemory(pCxtLink); + } + } + + return returnStatus; + +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + SentOption_GetParamBoolValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + BOOL* pBool + ); + + description: + + This function is called to retrieve Boolean parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + BOOL* pBool + The buffer of returned boolean value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +SentOption_GetParamBoolValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + BOOL* pBool + ) +{ + PCONTEXT_LINK_OBJECT pCxtLink = (PCONTEXT_LINK_OBJECT)hInsContext; + PCOSA_DML_DHCP_OPT pDhcpSendOption = (PCOSA_DML_DHCP_OPT)pCxtLink->hContext; + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + + /* check the parameter name and return the corresponding value */ + if( AnscEqualString(ParamName, "Enable", TRUE)) + { + /* collect value */ + *pBool = pDhcpSendOption->bEnabled; + + return TRUE; + } + + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + SentOption_GetParamIntValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + int* pInt + ); + + description: + + This function is called to retrieve integer parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + int* pInt + The buffer of returned integer value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +SentOption_GetParamIntValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + int* pInt + ) +{ + /* check the parameter name and return the corresponding value */ + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + UNREFERENCED_PARAMETER(hInsContext); + UNREFERENCED_PARAMETER(ParamName); + UNREFERENCED_PARAMETER(pInt); + + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + SentOption_GetParamUlongValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + ULONG* puLong + ); + + description: + + This function is called to retrieve ULONG parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + ULONG* puLong + The buffer of returned ULONG value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +SentOption_GetParamUlongValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + ULONG* puLong + ) +{ + PCONTEXT_LINK_OBJECT pCxtLink = (PCONTEXT_LINK_OBJECT)hInsContext; + PCOSA_DML_DHCP_OPT pDhcpSendOption = (PCOSA_DML_DHCP_OPT)pCxtLink->hContext; + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + + /* check the parameter name and return the corresponding value */ + if( AnscEqualString(ParamName, "Tag", TRUE)) + { + /* collect value */ + *puLong = pDhcpSendOption->Tag; + + return TRUE; + } + + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG + SentOption_GetParamStringValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + char* pValue, + ULONG* pUlSize + ); + + description: + + This function is called to retrieve string parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + char* pValue, + The string value buffer; + + ULONG* pUlSize + The buffer of length of string value; + Usually size of 1023 will be used. + If it's not big enough, put required size here and return 1; + + return: 0 if succeeded; + 1 if short of buffer size; (*pUlSize = required size) + -1 if not supported. + +**********************************************************************/ +ULONG +SentOption_GetParamStringValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + char* pValue, + ULONG* pUlSize + ) +{ + PCONTEXT_LINK_OBJECT pCxtLink = (PCONTEXT_LINK_OBJECT)hInsContext; + PCOSA_DML_DHCP_OPT pDhcpSendOption = (PCOSA_DML_DHCP_OPT)pCxtLink->hContext; + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + + /* check the parameter name and return the corresponding value */ + if( AnscEqualString(ParamName, "Alias", TRUE)) + { + /* collect value */ + if ( AnscSizeOfString(pDhcpSendOption->Alias) < *pUlSize) + { + AnscCopyString(pValue, pDhcpSendOption->Alias); + return 0; + } + else + { + *pUlSize = AnscSizeOfString(pDhcpSendOption->Alias)+1; + return 1; + } + } + + else if( AnscEqualString(ParamName, "Value", TRUE)) + { + /* collect value */ + if ( AnscSizeOfString((const char*)pDhcpSendOption->Value) < *pUlSize) + { + AnscCopyString(pValue, (char*)pDhcpSendOption->Value); + return 0; + } + else + { + *pUlSize = AnscSizeOfString((const char*)pDhcpSendOption->Value)+1; + return 1; + } + } + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return -1; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + SentOption_SetParamBoolValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + BOOL bValue + ); + + description: + + This function is called to set BOOL parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + BOOL bValue + The updated BOOL value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +SentOption_SetParamBoolValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + BOOL bValue + ) +{ + PCONTEXT_LINK_OBJECT pCxtLink = (PCONTEXT_LINK_OBJECT)hInsContext; + PCOSA_DML_DHCP_OPT pDhcpSendOption = (PCOSA_DML_DHCP_OPT)pCxtLink->hContext; + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "Enable", TRUE)) + { + /* save update to backup */ + pDhcpSendOption->bEnabled = bValue; + + return TRUE; + } + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + SentOption_SetParamIntValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + int iValue + ); + + description: + + This function is called to set integer parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + int iValue + The updated integer value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +SentOption_SetParamIntValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + int iValue + ) +{ + UNREFERENCED_PARAMETER(hInsContext); + UNREFERENCED_PARAMETER(ParamName); + UNREFERENCED_PARAMETER(iValue); + + /* check the parameter name and set the corresponding value */ + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + SentOption_SetParamUlongValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + ULONG uValue + ); + + description: + + This function is called to set ULONG parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + ULONG uValue + The updated ULONG value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +SentOption_SetParamUlongValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + ULONG uValue + ) +{ + PCONTEXT_LINK_OBJECT pCxtLink = (PCONTEXT_LINK_OBJECT)hInsContext; + PCOSA_DML_DHCP_OPT pDhcpSendOption = (PCOSA_DML_DHCP_OPT)pCxtLink->hContext; + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "Tag", TRUE)) + { + /* save update to backup */ + pDhcpSendOption->Tag = (UCHAR)uValue; + + return TRUE; + } + + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + SentOption_SetParamStringValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + char* pString + ); + + description: + + This function is called to set string parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + char* pString + The updated string value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +SentOption_SetParamStringValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + char* pString + ) +{ + PCONTEXT_LINK_OBJECT pCxtLink = (PCONTEXT_LINK_OBJECT)hInsContext; + PCOSA_DML_DHCP_OPT pDhcpSendOption = (PCOSA_DML_DHCP_OPT)pCxtLink->hContext; + PDHCPC_CONTEXT_LINK_OBJECT pCxtDhcpcLink = (PDHCPC_CONTEXT_LINK_OBJECT)pCxtLink->hParentTable; + PCONTEXT_LINK_OBJECT pCxtLink2 = NULL; + PCOSA_DML_DHCP_OPT pDhcpSendOption2 = NULL; + PSINGLE_LINK_ENTRY pSListEntry = NULL; + BOOL bFound = FALSE; + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "Alias", TRUE)) + { + AnscCopyString(pCxtDhcpcLink->AliasOfSend, pDhcpSendOption->Alias); + + AnscCopyString(pDhcpSendOption->Alias, pString); + + return TRUE; + } + + else if( AnscEqualString(ParamName, "Value", TRUE)) + { + /* save update to backup */ + AnscCopyString((char*)pDhcpSendOption->Value, pString); + + return TRUE; + } + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + SentOption_Validate + ( + ANSC_HANDLE hInsContext, + char* pReturnParamName, + ULONG* puLength + ); + + description: + + This function is called to finally commit all the update. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* pReturnParamName, + The buffer (128 bytes) of parameter name if there's a validation. + + ULONG* puLength + The output length of the param name. + + return: TRUE if there's no validation. + +**********************************************************************/ +BOOL +SentOption_Validate + ( + ANSC_HANDLE hInsContext, + char* pReturnParamName, + ULONG* puLength + ) +{ + UNREFERENCED_PARAMETER(puLength); + PCONTEXT_LINK_OBJECT pCxtLink = (PCONTEXT_LINK_OBJECT)hInsContext; + PCOSA_DML_DHCP_OPT pDhcpSendOption = (PCOSA_DML_DHCP_OPT)pCxtLink->hContext; + PDHCPC_CONTEXT_LINK_OBJECT pCxtDhcpcLink = (PDHCPC_CONTEXT_LINK_OBJECT)pCxtLink->hParentTable; + PCONTEXT_LINK_OBJECT pCxtLink2 = NULL; + PCOSA_DML_DHCP_OPT pDhcpSendOption2 = NULL; + PSINGLE_LINK_ENTRY pSListEntry = NULL; + BOOL bFound = FALSE; + + /* Parent hasn't set, we don't permit child is set.*/ + if ( pCxtDhcpcLink->bNew ) + { +#if COSA_DHCPV4_ROLLBACK_TEST + SentOption_Rollback(hInsContext); +#endif + return FALSE; + } + + /* This is for alias */ + if ( pCxtDhcpcLink->AliasOfSend[0] ) + { + bFound = FALSE; + pSListEntry = AnscSListGetFirstEntry(&pCxtDhcpcLink->SendOptionList); + while( pSListEntry != NULL) + { + pCxtLink2 = ACCESS_CONTEXT_LINK_OBJECT(pSListEntry); + pSListEntry = AnscSListGetNextEntry(pSListEntry); + + pDhcpSendOption2 = (PCOSA_DML_DHCP_OPT)pCxtLink2->hContext; + + if( DHCPV4_SENDOPTION_ENTRY_MATCH2(pDhcpSendOption->Alias, pDhcpSendOption2->Alias) ) + { + if ( (ANSC_HANDLE)pCxtLink2 == hInsContext ) + { + continue; + } + + _ansc_strcpy(pReturnParamName, "Alias"); + + bFound = TRUE; + + break; + } + } + + if ( bFound ) + { +#if COSA_DHCPV4_ROLLBACK_TEST + SentOption_Rollback(hInsContext); +#endif + return FALSE; + } + } + + /* For other check */ + + + return TRUE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG + SentOption_Commit + ( + ANSC_HANDLE hInsContext + ); + + description: + + This function is called to finally commit all the update. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: The status of the operation. + +**********************************************************************/ +ULONG +SentOption_Commit + ( + ANSC_HANDLE hInsContext + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PCONTEXT_LINK_OBJECT pCxtLink = (PCONTEXT_LINK_OBJECT)hInsContext; + PCOSA_DML_DHCP_OPT pDhcpSendOption = (PCOSA_DML_DHCP_OPT)pCxtLink->hContext; + PDHCPC_CONTEXT_LINK_OBJECT pCxtDhcpcLink = (PDHCPC_CONTEXT_LINK_OBJECT)pCxtLink->hParentTable; + PDML_DHCPC_FULL pDhcpClient = (PDML_DHCPC_FULL)pCxtDhcpcLink->hContext; + PWAN_DHCPV4_DATA pDhcpv4 = (PWAN_DHCPV4_DATA)g_pWanMgrBE->hDhcpv4; + + if (pDhcpv4 != NULL) + { + if ( pCxtLink->bNew ) + { + returnStatus = WanMgr_DmlDhcpcAddSentOption(NULL, pDhcpClient->Cfg.InstanceNumber, pDhcpSendOption ); + + if ( returnStatus == ANSC_STATUS_SUCCESS ) + { + pCxtLink->bNew = FALSE; + + WanMgr_Dhcpv4RegSetDhcpv4Info(pDhcpv4); + } + else + { + DHCPV4_SENDOPTION_SET_DEFAULTVALUE(pDhcpSendOption); + + if ( pCxtDhcpcLink->AliasOfSend[0] ) + AnscCopyString( pDhcpSendOption->Alias, pCxtDhcpcLink->AliasOfSend ); + } + } + else + { + returnStatus = WanMgr_DmlDhcpcSetSentOption(NULL, pDhcpClient->Cfg.InstanceNumber, pDhcpSendOption); + + if ( returnStatus != ANSC_STATUS_SUCCESS) + { + WanMgr_DmlDhcpcGetSentOptionbyInsNum(NULL, pDhcpClient->Cfg.InstanceNumber, pDhcpSendOption); + } + } + + AnscZeroMemory( pCxtDhcpcLink->AliasOfSend, sizeof(pCxtDhcpcLink->AliasOfSend) ); + } + + return returnStatus; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG + SentOption_Rollback + ( + ANSC_HANDLE hInsContext + ); + + description: + + This function is called to roll back the update whenever there's a + validation found. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: The status of the operation. + +**********************************************************************/ +ULONG +SentOption_Rollback + ( + ANSC_HANDLE hInsContext + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PCONTEXT_LINK_OBJECT pCxtLink = (PCONTEXT_LINK_OBJECT)hInsContext; + PCOSA_DML_DHCP_OPT pDhcpSendOption = (PCOSA_DML_DHCP_OPT)pCxtLink->hContext; + PDHCPC_CONTEXT_LINK_OBJECT pCxtDhcpcLink = (PDHCPC_CONTEXT_LINK_OBJECT)pCxtLink->hParentTable; + PDML_DHCPC_FULL pDhcpc = (PDML_DHCPC_FULL)pCxtDhcpcLink->hContext; + + if ( pCxtDhcpcLink->AliasOfSend[0] ) + AnscCopyString( pDhcpSendOption->Alias, pCxtDhcpcLink->AliasOfSend ); + + if ( !pCxtLink->bNew ) + { + WanMgr_DmlDhcpcGetSentOptionbyInsNum(NULL, pDhcpc->Cfg.InstanceNumber, pDhcpSendOption); + } + else + { + DHCPV4_SENDOPTION_SET_DEFAULTVALUE(pDhcpSendOption); + } + + AnscZeroMemory( pCxtDhcpcLink->AliasOfSend, sizeof(pCxtDhcpcLink->AliasOfSend) ); + + return returnStatus; +} + +/*********************************************************************** + + APIs for Object: + + DHCPv4.Client.{i}.ReqOption.{i}. + + * ReqOption_GetEntryCount + * ReqOption_GetEntry + * ReqOption_AddEntry + * ReqOption_DelEntry + * ReqOption_GetParamBoolValue + * ReqOption_GetParamIntValue + * ReqOption_GetParamUlongValue + * ReqOption_GetParamStringValue + * ReqOption_SetParamBoolValue + * ReqOption_SetParamIntValue + * ReqOption_SetParamUlongValue + * ReqOption_SetParamStringValue + * ReqOption_Validate + * ReqOption_Commit + * ReqOption_Rollback + +***********************************************************************/ +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG + ReqOption_GetEntryCount + ( + ANSC_HANDLE hInsContext + ); + + description: + + This function is called to retrieve the count of the table. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: The count of the table + +**********************************************************************/ +ULONG +ReqOption_GetEntryCount + ( + ANSC_HANDLE hInsContext + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PDHCPC_CONTEXT_LINK_OBJECT pCxtLink = (PDHCPC_CONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPC_FULL pDhcpc = (PDML_DHCPC_FULL)pCxtLink->hContext; + + return AnscSListQueryDepth( &pCxtLink->ReqOptionList ); +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ANSC_HANDLE + ReqOption_GetEntry + ( + ANSC_HANDLE hInsContext, + ULONG nIndex, + ULONG* pInsNumber + ); + + description: + + This function is called to retrieve the entry specified by the index. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + ULONG nIndex, + The index of this entry; + + ULONG* pInsNumber + The output instance number; + + return: The handle to identify the entry + +**********************************************************************/ +ANSC_HANDLE +ReqOption_GetEntry + ( + ANSC_HANDLE hInsContext, + ULONG nIndex, + ULONG* pInsNumber + ) +{ + PDHCPC_CONTEXT_LINK_OBJECT pCxtDhcpcLink = (PDHCPC_CONTEXT_LINK_OBJECT)hInsContext; + PCONTEXT_LINK_OBJECT pCxtLink = NULL; + PSINGLE_LINK_ENTRY pSListEntry = NULL; + + pSListEntry = AnscSListGetEntryByIndex(&pCxtDhcpcLink->ReqOptionList, nIndex); + + if ( pSListEntry ) + { + pCxtLink = ACCESS_CONTEXT_LINK_OBJECT(pSListEntry); + *pInsNumber = pCxtLink->InstanceNumber; + } + + return pSListEntry; +} + + +/********************************************************************** + + caller: owner of this object + + prototype: + + ANSC_HANDLE + ReqOption_AddEntry + ( + ANSC_HANDLE hInsContext, + ULONG* pInsNumber + ); + + description: + + This function is called to add a new entry. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + ULONG* pInsNumber + The output instance number; + + return: The handle of new added entry. + +**********************************************************************/ +ANSC_HANDLE +ReqOption_AddEntry + ( + ANSC_HANDLE hInsContext, + ULONG* pInsNumber + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PDHCPC_CONTEXT_LINK_OBJECT pCxtDhcpcLink = (PDHCPC_CONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPC_FULL pDhcpc = (PDML_DHCPC_FULL)pCxtDhcpcLink->hContext; + PCONTEXT_LINK_OBJECT pCxtLink = NULL; + PDML_DHCPC_REQ_OPT pDhcpReqOption = NULL; + CHAR tmpBuff[64] = {0}; + + /* We need ask from backend */ + pDhcpReqOption = (PDML_DHCPC_REQ_OPT)AnscAllocateMemory( sizeof(DML_DHCPC_REQ_OPT) ); + if ( !pDhcpReqOption ) + { + goto EXIT2; + } + + DHCPV4_REQOPTION_SET_DEFAULTVALUE(pDhcpReqOption); + + pCxtLink = (PCONTEXT_LINK_OBJECT)AnscAllocateMemory( sizeof(CONTEXT_LINK_OBJECT) ); + if ( !pCxtLink ) + { + goto EXIT1; + } + + pCxtLink->hContext = (ANSC_HANDLE)pDhcpReqOption; + pCxtLink->hParentTable = (ANSC_HANDLE)pCxtDhcpcLink; + pCxtLink->bNew = TRUE; + + if ( !++pCxtDhcpcLink->maxInstanceOfReq ) + { + pCxtDhcpcLink->maxInstanceOfReq = 1; + } + pDhcpReqOption->InstanceNumber = pCxtDhcpcLink->maxInstanceOfReq; + pCxtLink->InstanceNumber = pDhcpReqOption->InstanceNumber; + *pInsNumber = pDhcpReqOption->InstanceNumber; + + _ansc_sprintf( pDhcpReqOption->Alias, "ReqOption%lu", pDhcpReqOption->InstanceNumber); + + /* Put into our list */ + SListPushEntryByInsNum(&pCxtDhcpcLink->ReqOptionList, (PCONTEXT_LINK_OBJECT)pCxtLink); + + /* we recreate the configuration */ + PWAN_DHCPV4_DATA pDhcpv4 = (PWAN_DHCPV4_DATA)g_pWanMgrBE->hDhcpv4; + if (pDhcpv4 != NULL) + { + WanMgr_Dhcpv4RegSetDhcpv4Info(pDhcpv4); + } + + return (ANSC_HANDLE)pCxtLink; + +EXIT1: + + AnscFreeMemory(pDhcpReqOption); + +EXIT2: + + return NULL; +} + + +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG + ReqOption_DelEntry + ( + ANSC_HANDLE hInsContext, + ANSC_HANDLE hInstance + ); + + description: + + This function is called to delete an exist entry. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + ANSC_HANDLE hInstance + The exist entry handle; + + return: The status of the operation. + +**********************************************************************/ +ULONG +ReqOption_DelEntry + ( + ANSC_HANDLE hInsContext, + ANSC_HANDLE hInstance + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PDHCPC_CONTEXT_LINK_OBJECT pCxtDhcpcLink = (PDHCPC_CONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPC_FULL pDhcpClient = (PDML_DHCPC_FULL)pCxtDhcpcLink->hContext; + PCONTEXT_LINK_OBJECT pCxtLink = (PCONTEXT_LINK_OBJECT)hInstance; + PDML_DHCPC_REQ_OPT pDhcpReqOption = (PDML_DHCPC_REQ_OPT)pCxtLink->hContext; + PWAN_DHCPV4_DATA pDhcpv4 = (PWAN_DHCPV4_DATA)g_pWanMgrBE->hDhcpv4; + + if (pDhcpv4 != NULL) + { + if ( !pCxtLink->bNew ) + { + returnStatus = WanMgr_DmlDhcpcDelReqOption( NULL, pDhcpClient->Cfg.InstanceNumber, pDhcpReqOption->InstanceNumber ); + if ( returnStatus != ANSC_STATUS_SUCCESS ) + { + return returnStatus; + } + } + + if ( AnscSListPopEntryByLink(&pCxtDhcpcLink->ReqOptionList, &pCxtLink->Linkage) ) + { + WanMgr_Dhcpv4RegSetDhcpv4Info(pDhcpv4); + + AnscFreeMemory(pCxtLink->hContext); + AnscFreeMemory(pCxtLink); + } + } + + return returnStatus; + +} + + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + ReqOption_GetParamBoolValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + BOOL* pBool + ); + + description: + + This function is called to retrieve Boolean parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + BOOL* pBool + The buffer of returned boolean value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +ReqOption_GetParamBoolValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + BOOL* pBool + ) +{ + PCONTEXT_LINK_OBJECT pCxtLink = (PCONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPC_REQ_OPT pDhcpReqOption = (PDML_DHCPC_REQ_OPT)pCxtLink->hContext; + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + + /* check the parameter name and return the corresponding value */ + if( AnscEqualString(ParamName, "Enable", TRUE)) + { + /* collect value */ + *pBool = pDhcpReqOption->bEnabled; + + return TRUE; + } + + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + ReqOption_GetParamIntValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + int* pInt + ); + + description: + + This function is called to retrieve integer parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + int* pInt + The buffer of returned integer value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +ReqOption_GetParamIntValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + int* pInt + ) +{ + UNREFERENCED_PARAMETER(hInsContext); + UNREFERENCED_PARAMETER(ParamName); + UNREFERENCED_PARAMETER(pInt); + + /* check the parameter name and return the corresponding value */ + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + ReqOption_GetParamUlongValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + ULONG* puLong + ); + + description: + + This function is called to retrieve ULONG parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + ULONG* puLong + The buffer of returned ULONG value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +ReqOption_GetParamUlongValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + ULONG* puLong + ) +{ + PCONTEXT_LINK_OBJECT pCxtLink = (PCONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPC_REQ_OPT pDhcpReqOption = (PDML_DHCPC_REQ_OPT)pCxtLink->hContext; + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + + /* check the parameter name and return the corresponding value */ + if( AnscEqualString(ParamName, "Order", TRUE)) + { + /* collect value */ + *puLong = pDhcpReqOption->Order; + + return TRUE; + } + + else if( AnscEqualString(ParamName, "Tag", TRUE)) + { + /* collect value */ + *puLong = pDhcpReqOption->Tag; + + return TRUE; + } + + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG + ReqOption_GetParamStringValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + char* pValue, + ULONG* pUlSize + ); + + description: + + This function is called to retrieve string parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + char* pValue, + The string value buffer; + + ULONG* pUlSize + The buffer of length of string value; + Usually size of 1023 will be used. + If it's not big enough, put required size here and return 1; + + return: 0 if succeeded; + 1 if short of buffer size; (*pUlSize = required size) + -1 if not supported. + +**********************************************************************/ +ULONG +ReqOption_GetParamStringValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + char* pValue, + ULONG* pUlSize + ) +{ + PCONTEXT_LINK_OBJECT pCxtLink = (PCONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPC_REQ_OPT pDhcpReqOption = (PDML_DHCPC_REQ_OPT)pCxtLink->hContext; + PDHCPC_CONTEXT_LINK_OBJECT pCxtDhcpcLink = (PDHCPC_CONTEXT_LINK_OBJECT)pCxtLink->hParentTable; + PDML_DHCPC_FULL pDhcpc = (PDML_DHCPC_FULL)pCxtDhcpcLink->hContext; + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + + /* check the parameter name and return the corresponding value */ + if( AnscEqualString(ParamName, "Alias", TRUE)) + { + /* collect value */ + if ( AnscSizeOfString(pDhcpReqOption->Alias) < *pUlSize) + { + AnscCopyString(pValue, pDhcpReqOption->Alias); + return 0; + } + else + { + *pUlSize = AnscSizeOfString(pDhcpReqOption->Alias)+1; + return 1; + } + } + + else if( AnscEqualString(ParamName, "Value", TRUE)) + { + /* collect value */ + WanMgr_DmlDhcpcGetReqOptionbyInsNum(NULL, pDhcpc->Cfg.InstanceNumber, pDhcpReqOption); + + if ( AnscSizeOfString((const char*)pDhcpReqOption->Value) < *pUlSize) + { + AnscCopyString(pValue, (char*)pDhcpReqOption->Value); + return 0; + } + else + { + *pUlSize = AnscSizeOfString((const char*)pDhcpReqOption->Value)+1; + return 1; + } + } + + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return -1; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + ReqOption_SetParamBoolValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + BOOL bValue + ); + + description: + + This function is called to set BOOL parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + BOOL bValue + The updated BOOL value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +ReqOption_SetParamBoolValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + BOOL bValue + ) +{ + PCONTEXT_LINK_OBJECT pCxtLink = (PCONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPC_REQ_OPT pDhcpReqOption = (PDML_DHCPC_REQ_OPT)pCxtLink->hContext; + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "Enable", TRUE)) + { + /* save update to backup */ + pDhcpReqOption->bEnabled = bValue; + + return TRUE; + } + + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + ReqOption_SetParamIntValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + int iValue + ); + + description: + + This function is called to set integer parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + int iValue + The updated integer value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +ReqOption_SetParamIntValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + int iValue + ) +{ + UNREFERENCED_PARAMETER(hInsContext); + UNREFERENCED_PARAMETER(ParamName); + UNREFERENCED_PARAMETER(iValue); + + /* check the parameter name and set the corresponding value */ + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + ReqOption_SetParamUlongValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + ULONG uValue + ); + + description: + + This function is called to set ULONG parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + ULONG uValue + The updated ULONG value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +ReqOption_SetParamUlongValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + ULONG uValue + ) +{ + PCONTEXT_LINK_OBJECT pCxtLink = (PCONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPC_REQ_OPT pDhcpReqOption = (PDML_DHCPC_REQ_OPT)pCxtLink->hContext; + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "Order", TRUE)) + { + /* save update to backup */ + pDhcpReqOption->Order = uValue; + + return TRUE; + } + + else if( AnscEqualString(ParamName, "Tag", TRUE)) + { + /* save update to backup */ + pDhcpReqOption->Tag = (UCHAR)uValue; + + return TRUE; + } + + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + ReqOption_SetParamStringValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + char* pString + ); + + description: + + This function is called to set string parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + char* pString + The updated string value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +ReqOption_SetParamStringValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + char* pString + ) +{ + PCONTEXT_LINK_OBJECT pCxtLink = (PCONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPC_REQ_OPT pDhcpReqOption = (PDML_DHCPC_REQ_OPT)pCxtLink->hContext; + PDHCPC_CONTEXT_LINK_OBJECT pCxtDhcpcLink = (PDHCPC_CONTEXT_LINK_OBJECT)pCxtLink->hParentTable; + PCONTEXT_LINK_OBJECT pCxtLink2 = NULL; + PDML_DHCPC_REQ_OPT pDhcpReqOption2 = NULL; + PSINGLE_LINK_ENTRY pSListEntry = NULL; + BOOL bFound = FALSE; + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "Alias", TRUE)) + { + /* Backup old alias firstly */ + AnscCopyString(pCxtDhcpcLink->AliasOfReq, pDhcpReqOption->Alias); + + AnscCopyString(pDhcpReqOption->Alias, pString); + + return TRUE; + } + + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + ReqOption_Validate + ( + ANSC_HANDLE hInsContext, + char* pReturnParamName, + ULONG* puLength + ); + + description: + + This function is called to finally commit all the update. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* pReturnParamName, + The buffer (128 bytes) of parameter name if there's a validation. + + ULONG* puLength + The output length of the param name. + + return: TRUE if there's no validation. + +**********************************************************************/ +BOOL +ReqOption_Validate + ( + ANSC_HANDLE hInsContext, + char* pReturnParamName, + ULONG* puLength + ) +{ + PCONTEXT_LINK_OBJECT pCxtLink = (PCONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPC_REQ_OPT pDhcpReqOption = (PDML_DHCPC_REQ_OPT)pCxtLink->hContext; + PDHCPC_CONTEXT_LINK_OBJECT pCxtDhcpcLink = (PDHCPC_CONTEXT_LINK_OBJECT)pCxtLink->hParentTable; + PCONTEXT_LINK_OBJECT pCxtLink2 = NULL; + PDML_DHCPC_REQ_OPT pDhcpReqOption2 = NULL; + PSINGLE_LINK_ENTRY pSListEntry = NULL; + BOOL bFound = FALSE; + + UNREFERENCED_PARAMETER(puLength); + + /* Parent hasn't set, we don't permit child is set.*/ + if ( pCxtDhcpcLink->bNew ) + { +#if COSA_DHCPV4_ROLLBACK_TEST + ReqOption_Rollback(hInsContext); +#endif + + return FALSE; + } + + /* For other check */ + if ( pCxtDhcpcLink->AliasOfReq[0] ) + { + /* save update to backup */ + bFound = FALSE; + pSListEntry = AnscSListGetFirstEntry(&pCxtDhcpcLink->ReqOptionList); + while( pSListEntry != NULL) + { + pCxtLink2 = ACCESS_CONTEXT_LINK_OBJECT(pSListEntry); + pSListEntry = AnscSListGetNextEntry(pSListEntry); + + pDhcpReqOption2 = (PDML_DHCPC_REQ_OPT)pCxtLink2->hContext; + + if( DHCPV4_REQOPTION_ENTRY_MATCH2(pDhcpReqOption->Alias, pDhcpReqOption2->Alias ) ) + { + if ( (ANSC_HANDLE)pCxtLink2 == hInsContext ) + { + continue; + } + + _ansc_strcpy(pReturnParamName, "Alias"); + + bFound = TRUE; + + break; + } + } + + if ( bFound ) + { +#if COSA_DHCPV4_ROLLBACK_TEST + ReqOption_Rollback(hInsContext); +#endif + return FALSE; + } + } + + return TRUE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG + ReqOption_Commit + ( + ANSC_HANDLE hInsContext + ); + + description: + + This function is called to finally commit all the update. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: The status of the operation. + +**********************************************************************/ +ULONG +ReqOption_Commit + ( + ANSC_HANDLE hInsContext + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PCONTEXT_LINK_OBJECT pCxtLink = (PCONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPC_REQ_OPT pDhcpReqOption = (PDML_DHCPC_REQ_OPT)pCxtLink->hContext; + PDHCPC_CONTEXT_LINK_OBJECT pCxtDhcpcLink = (PDHCPC_CONTEXT_LINK_OBJECT)pCxtLink->hParentTable; + PDML_DHCPC_FULL pDhcpClient = (PDML_DHCPC_FULL)pCxtDhcpcLink->hContext; + PWAN_DHCPV4_DATA pDhcpv4 = (PWAN_DHCPV4_DATA)g_pWanMgrBE->hDhcpv4; + + if (pDhcpv4 != NULL) + { + if ( pCxtLink->bNew ) + { + returnStatus = WanMgr_DmlDhcpcAddReqOption(NULL, pDhcpClient->Cfg.InstanceNumber, pDhcpReqOption ); + + if ( returnStatus == ANSC_STATUS_SUCCESS ) + { + pCxtLink->bNew = FALSE; + + WanMgr_Dhcpv4RegSetDhcpv4Info(pDhcpv4); + } + else + { + DHCPV4_REQOPTION_SET_DEFAULTVALUE(pDhcpReqOption); + + if ( pCxtDhcpcLink->AliasOfReq[0] ) + AnscCopyString( pDhcpReqOption->Alias, pCxtDhcpcLink->AliasOfReq ); + } + } + else + { + returnStatus = WanMgr_DmlDhcpcSetReqOption(NULL, pDhcpClient->Cfg.InstanceNumber, pDhcpReqOption); + + if ( returnStatus != ANSC_STATUS_SUCCESS) + { + WanMgr_DmlDhcpcGetReqOptionbyInsNum(NULL, pDhcpClient->Cfg.InstanceNumber, pDhcpReqOption); + } + } + + AnscZeroMemory( pCxtDhcpcLink->AliasOfReq, sizeof(pCxtDhcpcLink->AliasOfReq) ); + } + + return returnStatus; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG + ReqOption_Rollback + ( + ANSC_HANDLE hInsContext + ); + + description: + + This function is called to roll back the update whenever there's a + validation found. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: The status of the operation. + +**********************************************************************/ +ULONG +ReqOption_Rollback + ( + ANSC_HANDLE hInsContext + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PCONTEXT_LINK_OBJECT pCxtLink = (PCONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPC_REQ_OPT pDhcpReqOption = (PDML_DHCPC_REQ_OPT)pCxtLink->hContext; + PDHCPC_CONTEXT_LINK_OBJECT pCxtDhcpcLink = (PDHCPC_CONTEXT_LINK_OBJECT)pCxtLink->hParentTable; + PDML_DHCPC_FULL pDhcpc = (PDML_DHCPC_FULL)pCxtDhcpcLink->hContext; + + if ( pCxtDhcpcLink->AliasOfReq[0] ) + AnscCopyString( pDhcpReqOption->Alias, pCxtDhcpcLink->AliasOfReq ); + + if ( !pCxtLink->bNew ) + { + WanMgr_DmlDhcpcGetReqOptionbyInsNum(NULL, pDhcpc->Cfg.InstanceNumber, pDhcpReqOption); + } + else + { + DHCPV4_REQOPTION_SET_DEFAULTVALUE(pDhcpReqOption); + } + + AnscZeroMemory( pCxtDhcpcLink->AliasOfReq, sizeof(pCxtDhcpcLink->AliasOfReq) ); + + return returnStatus; +} diff --git a/source/TR-181/middle_layer_src/wanmgr_dml_dhcpv4.h b/source/TR-181/middle_layer_src/wanmgr_dml_dhcpv4.h new file mode 100644 index 00000000..24776b08 --- /dev/null +++ b/source/TR-181/middle_layer_src/wanmgr_dml_dhcpv4.h @@ -0,0 +1,173 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2015 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +/********************************************************************** + Copyright [2014] [Cisco Systems, Inc.] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +**********************************************************************/ + +#ifndef _DHCPV4_DML_H +#define _DHCPV4_DML_H + +#include "wanmgr_apis.h" +/*********************************************************************** + + APIs for Object: + + DHCPv4. + + * DHCPv4_GetParamBoolValue + * DHCPv4_GetParamIntValue + * DHCPv4_GetParamUlongValue + * DHCPv4_GetParamStringValue + +***********************************************************************/ +BOOL DHCPv4_GetParamBoolValue ( ANSC_HANDLE hInsContext, char* ParamName, BOOL* pBool ); +BOOL DHCPv4_GetParamIntValue ( ANSC_HANDLE hInsContext, char* ParamName, int* pInt ); +BOOL DHCPv4_GetParamUlongValue ( ANSC_HANDLE hInsContext, char* ParamName, ULONG* pUlong ); +ULONG DHCPv4_GetParamStringValue ( ANSC_HANDLE hInsContext, char* ParamName, char* pValue, ULONG* pUlSize ); + +/*********************************************************************** + + APIs for Object: + + DHCPv4.Client.{i}. + + * Client_GetEntryCount + * Client_GetEntry + * Client_AddEntry + * Client_DelEntry + * Client_GetParamBoolValue + * Client_GetParamIntValue + * Client_GetParamUlongValue + * Client_GetParamStringValue + * Client_SetParamBoolValue + * Client_SetParamIntValue + * Client_SetParamUlongValue + * Client_SetParamStringValue + * Client_Validate + * Client_Commit + * Client_Rollback + +***********************************************************************/ +ULONG Client_GetEntryCount ( ANSC_HANDLE ); +ANSC_HANDLE Client_GetEntry ( ANSC_HANDLE hInsContext, ULONG nIndex, ULONG* pInsNumber ); +ANSC_HANDLE Client_AddEntry ( ANSC_HANDLE hInsContext, ULONG* pInsNumber ); +ULONG Client_DelEntry ( ANSC_HANDLE hInsContext, ANSC_HANDLE hInstance ); +BOOL Client_GetParamBoolValue ( ANSC_HANDLE hInsContext, char* ParamName, BOOL* pBool ); +BOOL Client_GetParamIntValue ( ANSC_HANDLE hInsContext, char* ParamName, int* pInt ); +BOOL Client_GetParamUlongValue ( ANSC_HANDLE hInsContext, char* ParamName, ULONG* pUlong ); +ULONG Client_GetParamStringValue ( ANSC_HANDLE hInsContext, char* ParamName, char* pValue, ULONG* pUlSize ); +BOOL Client_SetParamBoolValue ( ANSC_HANDLE hInsContext, char* ParamName, BOOL bValue ); +BOOL Client_SetParamIntValue ( ANSC_HANDLE hInsContext, char* ParamName, int value ); +BOOL Client_SetParamUlongValue ( ANSC_HANDLE hInsContext, char* ParamName, ULONG uValuepUlong ); +BOOL Client_SetParamStringValue ( ANSC_HANDLE hInsContext, char* ParamName, char* strValue ); +BOOL Client_Validate ( ANSC_HANDLE hInsContext, char* pReturnParamName, ULONG* puLength ); +ULONG Client_Commit ( ANSC_HANDLE hInsContext ); +ULONG Client_Rollback ( ANSC_HANDLE hInsContext ); + +/*********************************************************************** + + APIs for Object: + + DHCPv4.Client.{i}.SentOption.{i}. + + * SentOption_GetEntryCount + * SentOption_GetEntry + * SentOption_AddEntry + * SentOption_DelEntry + * SentOption_GetParamBoolValue + * SentOption_GetParamIntValue + * SentOption_GetParamUlongValue + * SentOption_GetParamStringValue + * SentOption_SetParamBoolValue + * SentOption_SetParamIntValue + * SentOption_SetParamUlongValue + * SentOption_SetParamStringValue + * SentOption_Validate + * SentOption_Commit + * SentOption_Rollback + +***********************************************************************/ +ULONG SentOption_GetEntryCount ( ANSC_HANDLE ); +ANSC_HANDLE SentOption_GetEntry ( ANSC_HANDLE hInsContext, ULONG nIndex, ULONG* pInsNumber ); +ANSC_HANDLE SentOption_AddEntry ( ANSC_HANDLE hInsContext, ULONG* pInsNumber ); +ULONG SentOption_DelEntry ( ANSC_HANDLE hInsContext, ANSC_HANDLE hInstance ); +BOOL SentOption_GetParamBoolValue ( ANSC_HANDLE hInsContext, char* ParamName, BOOL* pBool ); +BOOL SentOption_GetParamIntValue ( ANSC_HANDLE hInsContext, char* ParamName, int* pInt ); +BOOL SentOption_GetParamUlongValue ( ANSC_HANDLE hInsContext, char* ParamName, ULONG* pUlong ); +ULONG SentOption_GetParamStringValue ( ANSC_HANDLE hInsContext, char* ParamName, char* pValue, ULONG* pUlSize ); +BOOL SentOption_SetParamBoolValue ( ANSC_HANDLE hInsContext, char* ParamName, BOOL bValue ); +BOOL SentOption_SetParamIntValue ( ANSC_HANDLE hInsContext, char* ParamName, int value ); +BOOL SentOption_SetParamUlongValue ( ANSC_HANDLE hInsContext, char* ParamName, ULONG uValuepUlong ); +BOOL SentOption_SetParamStringValue ( ANSC_HANDLE hInsContext, char* ParamName, char* strValue ); +BOOL SentOption_Validate ( ANSC_HANDLE hInsContext, char* pReturnParamName, ULONG* puLength ); +ULONG SentOption_Commit ( ANSC_HANDLE hInsContext ); +ULONG SentOption_Rollback ( ANSC_HANDLE hInsContext ); + +/*********************************************************************** + + APIs for Object: + + DHCPv4.Client.{i}.ReqOption.{i}. + + * ReqOption_GetEntryCount + * ReqOption_GetEntry + * ReqOption_AddEntry + * ReqOption_DelEntry + * ReqOption_GetParamBoolValue + * ReqOption_GetParamIntValue + * ReqOption_GetParamUlongValue + * ReqOption_GetParamStringValue + * ReqOption_SetParamBoolValue + * ReqOption_SetParamIntValue + * ReqOption_SetParamUlongValue + * ReqOption_SetParamStringValue + * ReqOption_Validate + * ReqOption_Commit + * ReqOption_Rollback + +***********************************************************************/ +ULONG ReqOption_GetEntryCount ( ANSC_HANDLE ); +ANSC_HANDLE ReqOption_GetEntry ( ANSC_HANDLE hInsContext, ULONG nIndex, ULONG* pInsNumber ); +ANSC_HANDLE ReqOption_AddEntry ( ANSC_HANDLE hInsContext, ULONG* pInsNumber ); +ULONG ReqOption_DelEntry ( ANSC_HANDLE hInsContext, ANSC_HANDLE hInstance ); +BOOL ReqOption_GetParamBoolValue ( ANSC_HANDLE hInsContext, char* ParamName, BOOL* pBool ); +BOOL ReqOption_GetParamIntValue ( ANSC_HANDLE hInsContext, char* ParamName, int* pInt ); +BOOL ReqOption_GetParamUlongValue ( ANSC_HANDLE hInsContext, char* ParamName, ULONG* pUlong ); +ULONG ReqOption_GetParamStringValue ( ANSC_HANDLE hInsContext, char* ParamName, char* pValue, ULONG* pUlSize ); +BOOL ReqOption_SetParamBoolValue ( ANSC_HANDLE hInsContext, char* ParamName, BOOL bValue ); +BOOL ReqOption_SetParamIntValue ( ANSC_HANDLE hInsContext, char* ParamName, int value ); +BOOL ReqOption_SetParamUlongValue ( ANSC_HANDLE hInsContext, char* ParamName, ULONG uValuepUlong ); +BOOL ReqOption_SetParamStringValue ( ANSC_HANDLE hInsContext, char* ParamName, char* strValue ); +BOOL ReqOption_Validate ( ANSC_HANDLE hInsContext, char* pReturnParamName, ULONG* puLength ); +ULONG ReqOption_Commit ( ANSC_HANDLE hInsContext ); +ULONG ReqOption_Rollback ( ANSC_HANDLE hInsContext ); +#endif diff --git a/source/TR-181/middle_layer_src/wanmgr_dml_dhcpv6.c b/source/TR-181/middle_layer_src/wanmgr_dml_dhcpv6.c new file mode 100644 index 00000000..e09e565a --- /dev/null +++ b/source/TR-181/middle_layer_src/wanmgr_dml_dhcpv6.c @@ -0,0 +1,3573 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2015 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +/********************************************************************** + Copyright [2014] [Cisco Systems, Inc.] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +**********************************************************************/ + +#include "ansc_platform.h" +#include "wanmgr_plugin_main_apis.h" +#include "wanmgr_dhcpv6_apis.h" +#include "wanmgr_dhcpv6_internal.h" +#include + +extern int sysevent_fd; +extern token_t sysevent_token; +extern WANMGR_BACKEND_OBJ* g_pWanMgrBE; + +#define DATAMODEL_PARAM_LENGTH 256 +/*********************************************************************** + IMPORTANT NOTE: + + According to TR69 spec: + On successful receipt of a SetParameterValues RPC, the CPE MUST apply + the changes to all of the specified Parameters atomically. That is, either + all of the value changes are applied together, or none of the changes are + applied at all. In the latter case, the CPE MUST return a fault response + indicating the reason for the failure to apply the changes. + + The CPE MUST NOT apply any of the specified changes without applying all + of them. + + In order to set parameter values correctly, the back-end is required to + hold the updated values until "Validate" and "Commit" are called. Only after + all the "Validate" passed in different objects, the "Commit" will be called. + Otherwise, "Rollback" will be called instead. + + The sequence in COSA Data Model will be: + + SetParamBoolValue/SetParamIntValue/SetParamUlongValue/SetParamStringValue + -- Backup the updated values; + + if( Validate_XXX()) + { + Commit_XXX(); -- Commit the update all together in the same object + } + else + { + Rollback_XXX(); -- Remove the update at backup; + } + +***********************************************************************/ +/*********************************************************************** + + APIs for Object: + + DHCPv6. + + * DHCPv6_GetParamBoolValue + * DHCPv6_GetParamIntValue + * DHCPv6_GetParamUlongValue + * DHCPv6_GetParamStringValue + +***********************************************************************/ +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + DHCPv6_GetParamBoolValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + BOOL* pBool + ); + + description: + + This function is called to retrieve Boolean parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + BOOL* pBool + The buffer of returned boolean value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +DHCPv6_GetParamBoolValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + BOOL* pBool + ) +{ + /* check the parameter name and return the corresponding value */ + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + UNREFERENCED_PARAMETER(hInsContext); + UNREFERENCED_PARAMETER(ParamName); + UNREFERENCED_PARAMETER(pBool); + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + DHCPv6_GetParamIntValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + int* pInt + ); + + description: + + This function is called to retrieve integer parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + int* pInt + The buffer of returned integer value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +DHCPv6_GetParamIntValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + int* pInt + ) +{ + /* check the parameter name and return the corresponding value */ + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + UNREFERENCED_PARAMETER(hInsContext); + UNREFERENCED_PARAMETER(ParamName); + UNREFERENCED_PARAMETER(pInt); + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + DHCPv6_GetParamUlongValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + ULONG* puLong + ); + + description: + + This function is called to retrieve ULONG parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + ULONG* puLong + The buffer of returned ULONG value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +DHCPv6_GetParamUlongValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + ULONG* puLong + ) +{ + /* check the parameter name and return the corresponding value */ + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + UNREFERENCED_PARAMETER(hInsContext); + UNREFERENCED_PARAMETER(ParamName); + UNREFERENCED_PARAMETER(puLong); + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG + DHCPv6_GetParamStringValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + char* pValue, + ULONG* pUlSize + ); + + description: + + This function is called to retrieve string parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + char* pValue, + The string value buffer; + + ULONG* pUlSize + The buffer of length of string value; + Usually size of 1023 will be used. + If it's not big enough, put required size here and return 1; + + return: 0 if succeeded; + 1 if short of buffer size; (*pUlSize = required size) + -1 if not supported. + +**********************************************************************/ +ULONG +DHCPv6_GetParamStringValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + char* pValue, + ULONG* pUlSize + ) +{ + /* check the parameter name and return the corresponding value */ + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + UNREFERENCED_PARAMETER(hInsContext); + UNREFERENCED_PARAMETER(ParamName); + UNREFERENCED_PARAMETER(pValue); + UNREFERENCED_PARAMETER(pUlSize); + return -1; +} + +/*********************************************************************** + + APIs for Object: + + DHCPv6.Client.{i}. + + * Client3_GetEntryCount + * Client3_GetEntry + * Client3_AddEntry + * Client3_DelEntry + * Client3_GetParamBoolValue + * Client3_GetParamIntValue + * Client3_GetParamUlongValue + * Client3_GetParamStringValue + * Client3_SetParamBoolValue + * Client3_SetParamIntValue + * Client3_SetParamUlongValue + * Client3_SetParamStringValue + * Client3_Validate + * Client3_Commit + * Client3_Rollback + +***********************************************************************/ +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG + Client3_GetEntryCount + ( + ANSC_HANDLE hInsContext + ); + + description: + + This function is called to retrieve the count of the table. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: The count of the table + +**********************************************************************/ +ULONG +Client3_GetEntryCount + ( + ANSC_HANDLE hInsContext + ) +{ + UNREFERENCED_PARAMETER(hInsContext); + ULONG ClientCount = 0; + PWAN_DHCPV6_DATA pDhcpv6 = (PWAN_DHCPV6_DATA)g_pWanMgrBE->hDhcpv6; + if(pDhcpv6 != NULL) + { + ClientCount = AnscSListQueryDepth( &pDhcpv6->ClientList ); + } + + return ClientCount; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ANSC_HANDLE + Client3_GetEntry + ( + ANSC_HANDLE hInsContext, + ULONG nIndex, + ULONG* pInsNumber + ); + + description: + + This function is called to retrieve the entry specified by the index. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + ULONG nIndex, + The index of this entry; + + ULONG* pInsNumber + The output instance number; + + return: The handle to identify the entry + +**********************************************************************/ +ANSC_HANDLE +Client3_GetEntry + ( + ANSC_HANDLE hInsContext, + ULONG nIndex, + ULONG* pInsNumber + ) +{ + UNREFERENCED_PARAMETER(hInsContext); + PSINGLE_LINK_ENTRY pSListEntry = NULL; + PWAN_DHCPV6_DATA pDhcpv6 = (PWAN_DHCPV6_DATA)g_pWanMgrBE->hDhcpv6; + PDHCPCV6_CONTEXT_LINK_OBJECT pCxtLink = NULL; + + if (pDhcpv6 != NULL) + { + pSListEntry = AnscSListGetEntryByIndex(&pDhcpv6->ClientList, nIndex); + + if ( pSListEntry ) + { + pCxtLink = ACCESS_DHCPCV6_CONTEXT_LINK_OBJECT(pSListEntry); + *pInsNumber = pCxtLink->InstanceNumber; + } + } + + return pSListEntry; + +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ANSC_HANDLE + Client3_AddEntry + ( + ANSC_HANDLE hInsContext, + ULONG* pInsNumber + ); + + description: + + This function is called to add a new entry. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + ULONG* pInsNumber + The output instance number; + + return: The handle of new added entry. + +**********************************************************************/ +ANSC_HANDLE +Client3_AddEntry + ( + ANSC_HANDLE hInsContext, + ULONG* pInsNumber + ) +{ + UNREFERENCED_PARAMETER(hInsContext); + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PSINGLE_LINK_ENTRY pSListEntry = NULL; + PDHCPCV6_CONTEXT_LINK_OBJECT pCxtLink = NULL; + PDML_DHCPCV6_FULL pDhcpc = NULL; + PWAN_DHCPV6_DATA pDhcpv6 = (PWAN_DHCPV6_DATA)g_pWanMgrBE->hDhcpv6; + +#if (defined _COSA_DRG_CNS_) || (defined _COSA_DRG_TPG_) + /*not supported*/ + return NULL; +#endif + + if (pDhcpv6 != NULL) + { + pDhcpc = (PDML_DHCPCV6_FULL)AnscAllocateMemory( sizeof(DML_DHCPCV6_FULL) ); + if ( !pDhcpc ) + { + return NULL; /* return the handle */ + } + + /* Set default value */ + DHCPV6_CLIENT_SET_DEFAULTVALUE(pDhcpc); + + /* Add into our link tree*/ + pCxtLink = (PDHCPCV6_CONTEXT_LINK_OBJECT)AnscAllocateMemory( sizeof(DHCPCV6_CONTEXT_LINK_OBJECT) ); + if ( !pCxtLink ) + { + AnscFreeMemory(pDhcpc); + return NULL; + } + + DHCPV6_CLIENT_INITIATION_CONTEXT(pCxtLink) + + pCxtLink->hContext = (ANSC_HANDLE)pDhcpc; + pCxtLink->bNew = TRUE; + + if ( !++pDhcpv6->maxInstanceOfClient ) + { + pDhcpv6->maxInstanceOfClient = 1; + } + pDhcpc->Cfg.InstanceNumber = pDhcpv6->maxInstanceOfClient; + pCxtLink->InstanceNumber = pDhcpc->Cfg.InstanceNumber; + *pInsNumber = pDhcpc->Cfg.InstanceNumber; + + _ansc_sprintf( pDhcpc->Cfg.Alias, "Client%d", pDhcpc->Cfg.InstanceNumber); + + /* Put into our list */ + SListPushEntryByInsNum(&pDhcpv6->ClientList, (PCONTEXT_LINK_OBJECT)pCxtLink); + + /* we recreate the configuration because we has new delay_added entry for dhcpv6 */ + WanMgr_Dhcpv6RegSetDhcpv6Info(pDhcpv6); + + } + + return (ANSC_HANDLE)pCxtLink; + +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG + Client3_DelEntry + ( + ANSC_HANDLE hInsContext, + ANSC_HANDLE hInstance + ); + + description: + + This function is called to delete an exist entry. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + ANSC_HANDLE hInstance + The exist entry handle; + + return: The status of the operation. + +**********************************************************************/ +ULONG +Client3_DelEntry + ( + ANSC_HANDLE hInsContext, + ANSC_HANDLE hInstance + ) +{ + UNREFERENCED_PARAMETER(hInsContext); + UNREFERENCED_PARAMETER(hInstance); + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PSINGLE_LINK_ENTRY pSListEntry = NULL; + PWAN_DHCPV6_DATA pDhcpv6 = (PWAN_DHCPV6_DATA)g_pWanMgrBE->hDhcpv6; + PDHCPCV6_CONTEXT_LINK_OBJECT pCxtLink = (PDHCPCV6_CONTEXT_LINK_OBJECT)hInstance; + PCONTEXT_LINK_OBJECT pCxtLink2 = NULL; + PDML_DHCPCV6_FULL pDhcpc = (PDML_DHCPCV6_FULL)pCxtLink->hContext; + + /* Normally, two sublinks are empty because our framework will firstly + call delEntry for them before coming here. We needn't care them. + */ +#if (defined _COSA_DRG_CNS_) || (defined _COSA_DRG_TPG_) + /*not supported*/ + return ANSC_STATUS_FAILURE; +#endif + + if (pDhcpv6 != NULL) + { + if ( !pCxtLink->bNew ) + { + returnStatus = WanMgr_DmlDhcpv6cDelEntry(NULL, pDhcpc->Cfg.InstanceNumber); + if ( returnStatus != ANSC_STATUS_SUCCESS ) + { + return returnStatus; + } + } + + if (AnscSListPopEntryByLink(&pDhcpv6->ClientList, &pCxtLink->Linkage) ) + { + /* Because the current NextInstanceNumber information need be deleted */ + WanMgr_Dhcpv6RegSetDhcpv6Info(pDhcpv6); + + AnscFreeMemory(pCxtLink->hContext); + AnscFreeMemory(pCxtLink); + } + } + + return returnStatus; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + Client3_GetParamBoolValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + BOOL* pBool + ); + + description: + + This function is called to retrieve Boolean parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + BOOL* pBool + The buffer of returned boolean value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +Client3_GetParamBoolValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + BOOL* pBool + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PDHCPCV6_CONTEXT_LINK_OBJECT pCxtLink = (PDHCPCV6_CONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPCV6_FULL pDhcpc = (PDML_DHCPCV6_FULL)pCxtLink->hContext; + + /* check the parameter name and return the corresponding value */ + if( AnscEqualString(ParamName, "Enable", TRUE) ) + { + /* collect value */ + /**pBool = pDhcpc->Cfg.bEnabled;*/ + *pBool =WanMgr_DmlDhcpv6cGetEnabled(NULL); + + return TRUE; + } + + if( AnscEqualString(ParamName, "RequestAddresses", TRUE) ) + { + /* collect value */ + *pBool = pDhcpc->Cfg.RequestAddresses; + + return TRUE; + } + + if( AnscEqualString(ParamName, "RequestPrefixes", TRUE) ) + { + /* collect value */ + *pBool = pDhcpc->Cfg.RequestPrefixes; + + return TRUE; + } + + if( AnscEqualString(ParamName, "RapidCommit", TRUE) ) + { + /* collect value */ + *pBool = pDhcpc->Cfg.RapidCommit; + + return TRUE; + } + + if( AnscEqualString(ParamName, "Renew", TRUE) ) + { + /* collect value */ + *pBool = FALSE; + + return TRUE; + } + + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + Client3_GetParamIntValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + int* pInt + ); + + description: + + This function is called to retrieve integer parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + int* pInt + The buffer of returned integer value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +Client3_GetParamIntValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + int* pInt + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PDHCPCV6_CONTEXT_LINK_OBJECT pCxtLink = (PDHCPCV6_CONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPCV6_FULL pDhcpc = (PDML_DHCPCV6_FULL)pCxtLink->hContext; + + /* check the parameter name and return the corresponding value */ + if( AnscEqualString(ParamName, "SuggestedT1", TRUE) ) + { + /* collect value */ + *pInt = pDhcpc->Cfg.SuggestedT1; + + return TRUE; + } + + if( AnscEqualString(ParamName, "SuggestedT2", TRUE) ) + { + /* collect value */ + *pInt = pDhcpc->Cfg.SuggestedT2; + + return TRUE; + } + + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + Client3_GetParamUlongValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + ULONG* puLong + ); + + description: + + This function is called to retrieve ULONG parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + ULONG* puLong + The buffer of returned ULONG value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +Client3_GetParamUlongValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + ULONG* puLong + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PDHCPCV6_CONTEXT_LINK_OBJECT pCxtLink = (PDHCPCV6_CONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPCV6_FULL pDhcpc = (PDML_DHCPCV6_FULL)pCxtLink->hContext; + + /* check the parameter name and return the corresponding value */ + if( AnscEqualString(ParamName, "Status", TRUE) ) + { + /* collect value */ + WanMgr_DmlDhcpv6cGetInfo(pDhcpc, pCxtLink->InstanceNumber, &pDhcpc->Info); + + *puLong = pDhcpc->Info.Status; + + return TRUE; + } + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG + Client3_GetParamStringValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + char* pValue, + ULONG* pUlSize + ); + + description: + + This function is called to retrieve string parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + char* pValue, + The string value buffer; + + ULONG* pUlSize + The buffer of length of string value; + Usually size of 1023 will be used. + If it's not big enough, put required size here and return 1; + + return: 0 if succeeded; + 1 if short of buffer size; (*pUlSize = required size) + -1 if not supported. + +**********************************************************************/ +ULONG +Client3_GetParamStringValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + char* pValue, + ULONG* pUlSize + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PDHCPCV6_CONTEXT_LINK_OBJECT pCxtLink = (PDHCPCV6_CONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPCV6_FULL pDhcpc = (PDML_DHCPCV6_FULL)pCxtLink->hContext; + CHAR tmpBuff[DATAMODEL_PARAM_LENGTH] = {0}; + CHAR interface[DATAMODEL_PARAM_LENGTH] = {0}; + INT instanceNumber = -1; + ULONG i, len = 0; + /* check the parameter name and return the corresponding value */ + if( AnscEqualString(ParamName, "Alias", TRUE) ) + { + /* collect value */ + if ( AnscSizeOfString((const char*)pDhcpc->Cfg.Alias) < *pUlSize) + { + AnscCopyString(pValue, (char*)pDhcpc->Cfg.Alias); + return 0; + } + else + { + *pUlSize = AnscSizeOfString((const char*)pDhcpc->Cfg.Alias)+1; + return 1; + } + + return 0; + } + else if( AnscEqualString(ParamName, "Interface", TRUE) ) + { + DmlGetInstanceByKeywordFromPandM(pDhcpc->Cfg.Interface, &instanceNumber); + snprintf(interface, DATAMODEL_PARAM_LENGTH, PAM_IF_TABLE_OBJECT, instanceNumber); + if ( interface[0] != '\0' ) + { + if ( AnscSizeOfString(interface) < *pUlSize) + { + AnscCopyString(pValue, interface); + return 0; + } + else + { + *pUlSize = AnscSizeOfString(interface)+1; + return 1; + } + } + else + { + return 0; + } + + return 0; + } + else if( AnscEqualString(ParamName, "DUID", TRUE) ) + { + WanMgr_DmlDhcpv6cGetInfo(pDhcpc, pCxtLink->InstanceNumber, &pDhcpc->Info); + + /* collect value */ + if ( AnscSizeOfString((const char*)pDhcpc->Info.DUID) < *pUlSize) + { + AnscCopyString(pValue, (char*)pDhcpc->Info.DUID); + return 0; + } + else + { + *pUlSize = AnscSizeOfString((const char*)pDhcpc->Info.DUID)+1; + return 1; + } + } + else if( AnscEqualString(ParamName, "SupportedOptions", TRUE) ) + { + /* collect value */ + if ( AnscSizeOfString((const char*)pDhcpc->Info.SupportedOptions) < *pUlSize) + { + AnscCopyString(pValue, (char*)pDhcpc->Info.SupportedOptions); + return 0; + } + else + { + *pUlSize = AnscSizeOfString((const char*)pDhcpc->Info.SupportedOptions)+1; + return 1; + } + } + else if( AnscEqualString(ParamName, "RequestedOptions", TRUE) ) + { + /* collect value */ + if ( AnscSizeOfString((const char*)pDhcpc->Cfg.RequestedOptions) < *pUlSize) + { + AnscCopyString(pValue, (char*)pDhcpc->Cfg.RequestedOptions); + return 0; + } + else + { + *pUlSize = AnscSizeOfString((const char*)pDhcpc->Cfg.RequestedOptions)+1; + return 1; + } + } + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return -1; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + Client3_SetParamBoolValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + BOOL bValue + ); + + description: + + This function is called to set BOOL parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + BOOL bValue + The updated BOOL value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +Client3_SetParamBoolValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + BOOL bValue + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PDHCPCV6_CONTEXT_LINK_OBJECT pCxtLink = (PDHCPCV6_CONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPCV6_FULL pDhcpc = (PDML_DHCPCV6_FULL)pCxtLink->hContext; + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "Enable", TRUE) ) + { + /* save update to backup */ + pDhcpc->Cfg.bEnabled = bValue; + + return TRUE; + } + else if( AnscEqualString(ParamName, "RequestAddresses", TRUE) ) + { + /* save update to backup */ + pDhcpc->Cfg.RequestAddresses = bValue; + + return TRUE; + } + else if( AnscEqualString(ParamName, "RequestPrefixes", TRUE) ) + { + /* save update to backup */ + pDhcpc->Cfg.RequestPrefixes = bValue; + + return TRUE; + } + else if( AnscEqualString(ParamName, "RapidCommit", TRUE) ) + { + /* save update to backup */ + pDhcpc->Cfg.RapidCommit = bValue; + + return TRUE; + } + else if( AnscEqualString(ParamName, "Renew", TRUE) ) + { + /* save update to backup */ + if ( bValue ) + { + returnStatus = WanMgr_DmlDhcpv6cRenew(NULL, pDhcpc->Cfg.InstanceNumber); + if ( returnStatus != ANSC_STATUS_SUCCESS ) + { + return FALSE; + } + } + + return TRUE; + } + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + Client3_SetParamIntValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + int iValue + ); + + description: + + This function is called to set integer parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + int iValue + The updated integer value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +Client3_SetParamIntValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + int iValue + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PDHCPCV6_CONTEXT_LINK_OBJECT pCxtLink = (PDHCPCV6_CONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPCV6_FULL pDhcpc = (PDML_DHCPCV6_FULL)pCxtLink->hContext; + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "SuggestedT1", TRUE) ) + { + /* save update to backup */ + pDhcpc->Cfg.SuggestedT1 = iValue; + + return TRUE; + } + else if( AnscEqualString(ParamName, "SuggestedT2", TRUE) ) + { + /* save update to backup */ + pDhcpc->Cfg.SuggestedT2 = iValue; + + return TRUE; + } + + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + Client3_SetParamUlongValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + ULONG uValue + ); + + description: + + This function is called to set ULONG parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + ULONG uValue + The updated ULONG value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +Client3_SetParamUlongValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + ULONG uValue + ) +{ + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + UNREFERENCED_PARAMETER(hInsContext); + UNREFERENCED_PARAMETER(ParamName); + UNREFERENCED_PARAMETER(uValue); + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + Client3_SetParamStringValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + char* pString + ); + + description: + + This function is called to set string parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + char* pString + The updated string value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +Client3_SetParamStringValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + char* pString + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PDHCPCV6_CONTEXT_LINK_OBJECT pCxtLink = (PDHCPCV6_CONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPCV6_FULL pDhcpc = (PDML_DHCPCV6_FULL)pCxtLink->hContext; + PWAN_DHCPV6_DATA pDhcpv6 = (PWAN_DHCPV6_DATA)g_pWanMgrBE->hDhcpv6; + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "RequestedOptions", TRUE) ) + { + /* save update to backup */ + AnscCopyString(pDhcpc->Cfg.RequestedOptions, pString); + + return TRUE; + } + else if( AnscEqualString(ParamName, "Alias", TRUE) ) + { + /* save update to backup */ + AnscCopyString(pDhcpv6->AliasOfClient, pDhcpc->Cfg.Alias); + + AnscCopyString(pDhcpc->Cfg.Alias, pString); + + return TRUE; + } + else if( AnscEqualString(ParamName, "Interface", TRUE) ) + { +#if defined _COSA_DRG_CNS_ || defined _COSA_DRG_TPG_ + /*not supported*/ + return FALSE; +#endif + + /* save update to backup */ + AnscCopyString(pDhcpc->Cfg.Interface, pString); + + return TRUE; + } + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + Client3_Validate + ( + ANSC_HANDLE hInsContext, + char* pReturnParamName, + ULONG* puLength + ); + + description: + + This function is called to finally commit all the update. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* pReturnParamName, + The buffer (128 bytes) of parameter name if there's a validation. + + ULONG* puLength + The output length of the param name. + + return: TRUE if there's no validation. + +**********************************************************************/ +BOOL +Client3_Validate + ( + ANSC_HANDLE hInsContext, + char* pReturnParamName, + ULONG* puLength + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PWAN_DHCPV6_DATA pDhcpv6 = (PWAN_DHCPV6_DATA)g_pWanMgrBE->hDhcpv6; + PDHCPCV6_CONTEXT_LINK_OBJECT pCxtLink = (PDHCPCV6_CONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPCV6_FULL pDhcpc = (PDML_DHCPCV6_FULL)pCxtLink->hContext; + PSINGLE_LINK_ENTRY pSListEntry = NULL; + PDML_DHCPCV6_FULL pDhcpc2 = NULL; + BOOL bFound = FALSE; + UNREFERENCED_PARAMETER(puLength); + if (pDhcpv6 != NULL) + { + /* only for Alias */ + if ( pDhcpv6->AliasOfClient[0] ) + { + pSListEntry = AnscSListGetFirstEntry(&pDhcpv6->ClientList); + while( pSListEntry != NULL) + { + pCxtLink = ACCESS_DHCPCV6_CONTEXT_LINK_OBJECT(pSListEntry); + pSListEntry = AnscSListGetNextEntry(pSListEntry); + + pDhcpc2 = (PDML_DHCPCV6_FULL)pCxtLink->hContext; + + if( DHCPV6_CLIENT_ENTRY_MATCH2((char*)pDhcpc2->Cfg.Alias, pDhcpc->Cfg.Alias) ) + { + if ( (ANSC_HANDLE)pCxtLink == hInsContext ) + { + continue; + } + + _ansc_strcpy(pReturnParamName, "Alias"); + + bFound = TRUE; + + break; + } + } + + if ( bFound ) + { +#if COSA_DHCPV6_ROLLBACK_TEST + Client3_Rollback(hInsContext); +#endif + return FALSE; + } + } + + /* some other checking */ + if (pDhcpc->Cfg.bEnabled) + { + if (pDhcpc->Cfg.SuggestedT1 > pDhcpc->Cfg.SuggestedT2) + { + return FALSE; + } + } + } + + return TRUE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG + Client3_Commit + ( + ANSC_HANDLE hInsContext + ); + + description: + + This function is called to finally commit all the update. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: The status of the operation. + +**********************************************************************/ +ULONG +Client3_Commit + ( + ANSC_HANDLE hInsContext + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PDHCPCV6_CONTEXT_LINK_OBJECT pCxtLink = (PDHCPCV6_CONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPCV6_FULL pDhcpc = (PDML_DHCPCV6_FULL)pCxtLink->hContext; + PWAN_DHCPV6_DATA pDhcpv6 = (PWAN_DHCPV6_DATA)g_pWanMgrBE->hDhcpv6; + + if (pDhcpv6 != NULL) + { + if ( pCxtLink->bNew ) + { + returnStatus = WanMgr_DmlDhcpv6cAddEntry(NULL, pDhcpc ); + + if ( returnStatus == ANSC_STATUS_SUCCESS ) + { + pCxtLink->bNew = FALSE; + + WanMgr_Dhcpv6RegSetDhcpv6Info(pDhcpv6); + } + else + { + DHCPV6_CLIENT_SET_DEFAULTVALUE(pDhcpc); + + if ( pDhcpv6->AliasOfClient[0] ) + AnscCopyString( (char*)pDhcpc->Cfg.Alias, pDhcpv6->AliasOfClient ); + } + } + else + { + returnStatus = WanMgr_DmlDhcpv6cSetCfg(NULL, &pDhcpc->Cfg); + + if ( returnStatus != ANSC_STATUS_SUCCESS) + { + WanMgr_DmlDhcpv6cGetCfg(NULL, &pDhcpc->Cfg); + } + } + + AnscZeroMemory( pDhcpv6->AliasOfClient, sizeof(pDhcpv6->AliasOfClient) ); + } + + return returnStatus; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG + Client3_Rollback + ( + ANSC_HANDLE hInsContext + ); + + description: + + This function is called to roll back the update whenever there's a + validation found. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: The status of the operation. + +**********************************************************************/ +ULONG +Client3_Rollback + ( + ANSC_HANDLE hInsContext + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PWAN_DHCPV6_DATA pDhcpv6 = (PWAN_DHCPV6_DATA)g_pWanMgrBE->hDhcpv6; + PDHCPCV6_CONTEXT_LINK_OBJECT pCxtLink = (PDHCPCV6_CONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPCV6_FULL pDhcpc = (PDML_DHCPCV6_FULL)pCxtLink->hContext; + + if (pDhcpv6 != NULL) + { + if ( pDhcpv6->AliasOfClient[0] ) + AnscCopyString( (char*)pDhcpc->Cfg.Alias, pDhcpv6->AliasOfClient ); + + if ( !pCxtLink->bNew ) + { + WanMgr_DmlDhcpv6cGetCfg( NULL, &pDhcpc->Cfg ); + } + else + { + DHCPV6_CLIENT_SET_DEFAULTVALUE(pDhcpc); + } + + AnscZeroMemory( pDhcpv6->AliasOfClient, sizeof(pDhcpv6->AliasOfClient) ); + } + + return returnStatus; +} + +/*********************************************************************** + + APIs for Object: + + DHCPv6.Client.{i}.Server.{i}. + + * Server2_GetEntryCount + * Server2_GetEntry + * Server2_IsUpdated + * Server2_Synchronize + * Server2_GetParamBoolValue + * Server2_GetParamIntValue + * Server2_GetParamUlongValue + * Server2_GetParamStringValue + +***********************************************************************/ +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG + Server2_GetEntryCount + ( + ANSC_HANDLE hInsContext + ); + + description: + + This function is called to retrieve the count of the table. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: The count of the table + +**********************************************************************/ +ULONG +Server2_GetEntryCount + ( + ANSC_HANDLE hInsContext + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PDHCPCV6_CONTEXT_LINK_OBJECT pCxtLink = (PDHCPCV6_CONTEXT_LINK_OBJECT)hInsContext; + + return (pCxtLink->NumberOfServer); +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ANSC_HANDLE + Server2_GetEntry + ( + ANSC_HANDLE hInsContext, + ULONG nIndex, + ULONG* pInsNumber + ); + + description: + + This function is called to retrieve the entry specified by the index. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + ULONG nIndex, + The index of this entry; + + ULONG* pInsNumber + The output instance number; + + return: The handle to identify the entry + +**********************************************************************/ +ANSC_HANDLE +Server2_GetEntry + ( + ANSC_HANDLE hInsContext, + ULONG nIndex, + ULONG* pInsNumber + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PDHCPCV6_CONTEXT_LINK_OBJECT pCxtLink = (PDHCPCV6_CONTEXT_LINK_OBJECT)hInsContext; + + *pInsNumber = nIndex + 1; + + return (ANSC_HANDLE)&pCxtLink->pServerEntry[nIndex]; /* return the handle */ +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + Server2_IsUpdated + ( + ANSC_HANDLE hInsContext + ); + + description: + + This function is checking whether the table is updated or not. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: TRUE or FALSE. + +**********************************************************************/ +BOOL +Server2_IsUpdated + ( + ANSC_HANDLE hInsContext + ) +{ + PDHCPCV6_CONTEXT_LINK_OBJECT pCxtLink = (PDHCPCV6_CONTEXT_LINK_OBJECT)hInsContext; + BOOL bIsUpdated = TRUE; + + /* + We can use one rough granularity interval to get whole table in case + that the updating is too frequent. + */ + if ( ( AnscGetTickInSeconds() - pCxtLink->PreviousVisitTimeOfServer ) < COSA_DML_DHCPV6_ACCESS_INTERVAL_CLIENTSERVER ) + { + bIsUpdated = FALSE; + } + else + { + pCxtLink->PreviousVisitTimeOfServer = AnscGetTickInSeconds(); + bIsUpdated = TRUE; + } + + return bIsUpdated; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG + Server2_Synchronize + ( + ANSC_HANDLE hInsContext + ); + + description: + + This function is called to synchronize the table. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: The status of the operation. + +**********************************************************************/ +ULONG +Server2_Synchronize + ( + ANSC_HANDLE hInsContext + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PDHCPCV6_CONTEXT_LINK_OBJECT pCxtLink = (PDHCPCV6_CONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPCV6_SVR pDhcpcServer = NULL; + ULONG count = 0; + + if ( pCxtLink->pServerEntry ) + { + AnscFreeMemory(pCxtLink->pServerEntry); + pCxtLink->pServerEntry = NULL; + pCxtLink->NumberOfServer = 0; + } + + returnStatus = WanMgr_DmlDhcpv6cGetServerCfg + ( + NULL, + pCxtLink->InstanceNumber, + &pDhcpcServer, + &count + ); + + if ( returnStatus == ANSC_STATUS_SUCCESS ) + { + pCxtLink->pServerEntry = pDhcpcServer; + pCxtLink->NumberOfServer = count; + } + + return returnStatus; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + Server2_GetParamBoolValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + BOOL* pBool + ); + + description: + + This function is called to retrieve Boolean parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + BOOL* pBool + The buffer of returned boolean value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +Server2_GetParamBoolValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + BOOL* pBool + ) +{ + /* check the parameter name and return the corresponding value */ + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + UNREFERENCED_PARAMETER(hInsContext); + UNREFERENCED_PARAMETER(ParamName); + UNREFERENCED_PARAMETER(pBool); + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + Server2_GetParamIntValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + int* pInt + ); + + description: + + This function is called to retrieve integer parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + int* pInt + The buffer of returned integer value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +Server2_GetParamIntValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + int* pInt + ) +{ + /* check the parameter name and return the corresponding value */ + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + UNREFERENCED_PARAMETER(hInsContext); + UNREFERENCED_PARAMETER(ParamName); + UNREFERENCED_PARAMETER(pInt); + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + Server2_GetParamUlongValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + ULONG* puLong + ); + + description: + + This function is called to retrieve ULONG parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + ULONG* puLong + The buffer of returned ULONG value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +Server2_GetParamUlongValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + ULONG* puLong + ) +{ + /* check the parameter name and return the corresponding value */ + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + UNREFERENCED_PARAMETER(hInsContext); + UNREFERENCED_PARAMETER(ParamName); + UNREFERENCED_PARAMETER(puLong); + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG + Server2_GetParamStringValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + char* pValue, + ULONG* pUlSize + ); + + description: + + This function is called to retrieve string parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + char* pValue, + The string value buffer; + + ULONG* pUlSize + The buffer of length of string value; + Usually size of 1023 will be used. + If it's not big enough, put required size here and return 1; + + return: 0 if succeeded; + 1 if short of buffer size; (*pUlSize = required size) + -1 if not supported. + +**********************************************************************/ +ULONG +Server2_GetParamStringValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + char* pValue, + ULONG* pUlSize + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PDML_DHCPCV6_SVR pDhcpcServer = (PDML_DHCPCV6_SVR)hInsContext; + + /* check the parameter name and return the corresponding value */ + if( AnscEqualString(ParamName, "SourceAddress", TRUE) ) + { + /* collect value */ + if ( AnscSizeOfString((const char*)pDhcpcServer->SourceAddress) < *pUlSize) + { + AnscCopyString(pValue, (char*)pDhcpcServer->SourceAddress); + return 0; + } + else + { + *pUlSize = AnscSizeOfString((const char*)pDhcpcServer->SourceAddress)+1; + return 1; + } + + return 0; + } + else if( AnscEqualString(ParamName, "DUID", TRUE) ) + { + /* collect value */ + if ( AnscSizeOfString((const char*)pDhcpcServer->DUID) < *pUlSize) + { + AnscCopyString(pValue, (char*)pDhcpcServer->DUID); + return 0; + } + else + { + *pUlSize = AnscSizeOfString((const char*)pDhcpcServer->DUID)+1; + return 1; + } + return 0; + } + else if( AnscEqualString(ParamName, "InformationRefreshTime", TRUE) ) + { + /* collect value */ + if ( AnscSizeOfString((const char*)pDhcpcServer->InformationRefreshTime) < *pUlSize) + { + AnscCopyString(pValue, (char*)pDhcpcServer->InformationRefreshTime); + return 0; + } + else + { + *pUlSize = AnscSizeOfString((const char*)pDhcpcServer->InformationRefreshTime)+1; + return 1; + } + return 0; + } + + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return -1; +} + +/*********************************************************************** + + APIs for Object: + + DHCPv6.Client.{i}.SentOption.{i}. + + * SentOption1_GetEntryCount + * SentOption1_GetEntry + * SentOption1_AddEntry + * SentOption1_DelEntry + * SentOption1_GetParamBoolValue + * SentOption1_GetParamIntValue + * SentOption1_GetParamUlongValue + * SentOption1_GetParamStringValue + * SentOption1_SetParamBoolValue + * SentOption1_SetParamIntValue + * SentOption1_SetParamUlongValue + * SentOption1_SetParamStringValue + * SentOption1_Validate + * SentOption1_Commit + * SentOption1_Rollback + +***********************************************************************/ +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG + SentOption1_GetEntryCount + ( + ANSC_HANDLE hInsContext + ); + + description: + + This function is called to retrieve the count of the table. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: The count of the table + +**********************************************************************/ +ULONG +SentOption1_GetEntryCount + ( + ANSC_HANDLE hInsContext + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PDHCPCV6_CONTEXT_LINK_OBJECT pCxtLink = (PDHCPCV6_CONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPCV6_FULL pDhcpc = (PDML_DHCPCV6_FULL)pCxtLink->hContext; + + return AnscSListQueryDepth( &pCxtLink->SentOptionList ); +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ANSC_HANDLE + SentOption1_GetEntry + ( + ANSC_HANDLE hInsContext, + ULONG nIndex, + ULONG* pInsNumber + ); + + description: + + This function is called to retrieve the entry specified by the index. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + ULONG nIndex, + The index of this entry; + + ULONG* pInsNumber + The output instance number; + + return: The handle to identify the entry + +**********************************************************************/ +ANSC_HANDLE +SentOption1_GetEntry + ( + ANSC_HANDLE hInsContext, + ULONG nIndex, + ULONG* pInsNumber + ) +{ + PDHCPCV6_CONTEXT_LINK_OBJECT pCxtDhcpcLink = (PDHCPCV6_CONTEXT_LINK_OBJECT)hInsContext; + PCONTEXT_LINK_OBJECT pCxtLink = NULL; + PSINGLE_LINK_ENTRY pSListEntry = NULL; + + pSListEntry = AnscSListGetEntryByIndex(&pCxtDhcpcLink->SentOptionList, nIndex); + + if ( pSListEntry ) + { + pCxtLink = ACCESS_CONTEXT_LINK_OBJECT(pSListEntry); + *pInsNumber = pCxtLink->InstanceNumber; + } + + return pSListEntry; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ANSC_HANDLE + SentOption1_AddEntry + ( + ANSC_HANDLE hInsContext, + ULONG* pInsNumber + ); + + description: + + This function is called to add a new entry. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + ULONG* pInsNumber + The output instance number; + + return: The handle of new added entry. + +**********************************************************************/ +ANSC_HANDLE +SentOption1_AddEntry + ( + ANSC_HANDLE hInsContext, + ULONG* pInsNumber + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PDHCPCV6_CONTEXT_LINK_OBJECT pCxtDhcpcLink = (PDHCPCV6_CONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPCV6_FULL pDhcpc = (PDML_DHCPCV6_FULL)pCxtDhcpcLink->hContext; + PCONTEXT_LINK_OBJECT pCxtLink = NULL; + PDML_DHCPCV6_SENT pDhcpSentOption = NULL; + + pDhcpSentOption = (PDML_DHCPCV6_SENT)AnscAllocateMemory( sizeof(DML_DHCPCV6_SENT) ); + if ( !pDhcpSentOption ) + { + goto EXIT2; + } + + DHCPV6_SENTOPTION_SET_DEFAULTVALUE(pDhcpSentOption); + + pCxtLink = (PCONTEXT_LINK_OBJECT)AnscAllocateMemory( sizeof(CONTEXT_LINK_OBJECT) ); + if ( !pCxtLink ) + { + goto EXIT1; + } + + pCxtLink->hContext = (ANSC_HANDLE)pDhcpSentOption; + pCxtLink->hParentTable = (ANSC_HANDLE)pCxtDhcpcLink; + pCxtLink->bNew = TRUE; + + if ( !++pCxtDhcpcLink->maxInstanceOfSent ) + { + pCxtDhcpcLink->maxInstanceOfSent = 1; + } + + pDhcpSentOption->InstanceNumber = pCxtDhcpcLink->maxInstanceOfSent; + pCxtLink->InstanceNumber = pDhcpSentOption->InstanceNumber; + *pInsNumber = pDhcpSentOption->InstanceNumber; + + _ansc_sprintf( (char*)pDhcpSentOption->Alias, "SentOption%d", pDhcpSentOption->InstanceNumber); + + /* Put into our list */ + SListPushEntryByInsNum(&pCxtDhcpcLink->SentOptionList, (PCONTEXT_LINK_OBJECT)pCxtLink); + + /* we recreate the configuration */ + PWAN_DHCPV6_DATA pDhcpv6 = (PWAN_DHCPV6_DATA)g_pWanMgrBE->hDhcpv6; + if (pDhcpv6 != NULL) + { + WanMgr_Dhcpv6RegSetDhcpv6Info(pDhcpv6); + } + + return (ANSC_HANDLE)pCxtLink; + +EXIT1: + + AnscFreeMemory(pDhcpSentOption); + +EXIT2: + + return NULL; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG + SentOption1_DelEntry + ( + ANSC_HANDLE hInsContext, + ANSC_HANDLE hInstance + ); + + description: + + This function is called to delete an exist entry. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + ANSC_HANDLE hInstance + The exist entry handle; + + return: The status of the operation. + +**********************************************************************/ +ULONG +SentOption1_DelEntry + ( + ANSC_HANDLE hInsContext, + ANSC_HANDLE hInstance + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PWAN_DHCPV6_DATA pDhcpv6 = (PWAN_DHCPV6_DATA)g_pWanMgrBE->hDhcpv6; + PDHCPCV6_CONTEXT_LINK_OBJECT pCxtDhcpcLink = (PDHCPCV6_CONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPCV6_FULL pDhcpClient = (PDML_DHCPCV6_FULL)pCxtDhcpcLink->hContext; + PCONTEXT_LINK_OBJECT pCxtLink = (PCONTEXT_LINK_OBJECT)hInstance; + PDML_DHCPCV6_SENT pDhcpSentOption = (PDML_DHCPCV6_SENT)pCxtLink->hContext; + + if (pDhcpv6 != NULL) + { + if ( !pCxtLink->bNew ) + { + returnStatus = WanMgr_DmlDhcpv6cDelSentOption(NULL, pDhcpClient->Cfg.InstanceNumber, pDhcpSentOption->InstanceNumber); + if ( returnStatus != ANSC_STATUS_SUCCESS ) + { + return returnStatus; + } + } + + if ( AnscSListPopEntryByLink(&pCxtDhcpcLink->SentOptionList, &pCxtLink->Linkage) ) + { + WanMgr_Dhcpv6RegSetDhcpv6Info(pDhcpv6); + AnscFreeMemory(pCxtLink->hContext); + AnscFreeMemory(pCxtLink); + } + } + + return returnStatus; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + SentOption1_GetParamBoolValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + BOOL* pBool + ); + + description: + + This function is called to retrieve Boolean parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + BOOL* pBool + The buffer of returned boolean value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +SentOption1_GetParamBoolValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + BOOL* pBool + ) +{ + PCONTEXT_LINK_OBJECT pCxtLink = (PCONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPCV6_SENT pDhcpSentOption = (PDML_DHCPCV6_SENT)pCxtLink->hContext; + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + + /* check the parameter name and return the corresponding value */ + if( AnscEqualString(ParamName, "Enable", TRUE) ) + { + /* collect value */ + *pBool = pDhcpSentOption->bEnabled; + + return TRUE; + } + + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + SentOption1_GetParamIntValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + int* pInt + ); + + description: + + This function is called to retrieve integer parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + int* pInt + The buffer of returned integer value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +SentOption1_GetParamIntValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + int* pInt + ) +{ + /* check the parameter name and return the corresponding value */ + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + UNREFERENCED_PARAMETER(hInsContext); + UNREFERENCED_PARAMETER(ParamName); + UNREFERENCED_PARAMETER(pInt); + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + SentOption1_GetParamUlongValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + ULONG* puLong + ); + + description: + + This function is called to retrieve ULONG parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + ULONG* puLong + The buffer of returned ULONG value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +SentOption1_GetParamUlongValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + ULONG* puLong + ) +{ + PCONTEXT_LINK_OBJECT pCxtLink = (PCONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPCV6_SENT pDhcpSentOption = (PDML_DHCPCV6_SENT)pCxtLink->hContext; + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + + /* check the parameter name and return the corresponding value */ + if( AnscEqualString(ParamName, "Tag", TRUE) ) + { + /* collect value */ + *puLong = pDhcpSentOption->Tag; + + return TRUE; + } + + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG + SentOption1_GetParamStringValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + char* pValue, + ULONG* pUlSize + ); + + description: + + This function is called to retrieve string parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + char* pValue, + The string value buffer; + + ULONG* pUlSize + The buffer of length of string value; + Usually size of 1023 will be used. + If it's not big enough, put required size here and return 1; + + return: 0 if succeeded; + 1 if short of buffer size; (*pUlSize = required size) + -1 if not supported. + +**********************************************************************/ +ULONG +SentOption1_GetParamStringValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + char* pValue, + ULONG* pUlSize + ) +{ + PCONTEXT_LINK_OBJECT pCxtLink = (PCONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPCV6_SENT pDhcpSentOption = (PDML_DHCPCV6_SENT)pCxtLink->hContext; + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + + /* check the parameter name and return the corresponding value */ + if( AnscEqualString(ParamName, "Alias", TRUE) ) + { + /* collect value */ + if ( AnscSizeOfString((const char*)pDhcpSentOption->Alias) < *pUlSize) + { + AnscCopyString(pValue, (char*)pDhcpSentOption->Alias); + return 0; + } + else + { + *pUlSize = AnscSizeOfString((const char*)pDhcpSentOption->Alias)+1; + return 1; + } + } + else if( AnscEqualString(ParamName, "Value", TRUE) ) + { + /* collect value */ + if ( AnscSizeOfString((const char*)pDhcpSentOption->Value) < *pUlSize) + { + AnscCopyString(pValue, (char*)pDhcpSentOption->Value); + return 0; + } + else + { + *pUlSize = AnscSizeOfString((const char*)pDhcpSentOption->Value)+1; + return 1; + } + } + + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return -1; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + SentOption1_SetParamBoolValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + BOOL bValue + ); + + description: + + This function is called to set BOOL parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + BOOL bValue + The updated BOOL value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +SentOption1_SetParamBoolValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + BOOL bValue + ) +{ + PCONTEXT_LINK_OBJECT pCxtLink = (PCONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPCV6_SENT pDhcpSentOption = (PDML_DHCPCV6_SENT)pCxtLink->hContext; + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "Enable", TRUE) ) + { + /* save update to backup */ + pDhcpSentOption->bEnabled = bValue; + + return TRUE; + } + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + SentOption1_SetParamIntValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + int iValue + ); + + description: + + This function is called to set integer parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + int iValue + The updated integer value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +SentOption1_SetParamIntValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + int iValue + ) +{ + /* check the parameter name and set the corresponding value */ + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + UNREFERENCED_PARAMETER(hInsContext); + UNREFERENCED_PARAMETER(ParamName); + UNREFERENCED_PARAMETER(iValue); + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + SentOption1_SetParamUlongValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + ULONG uValue + ); + + description: + + This function is called to set ULONG parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + ULONG uValue + The updated ULONG value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +SentOption1_SetParamUlongValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + ULONG uValue + ) +{ + PCONTEXT_LINK_OBJECT pCxtLink = (PCONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPCV6_SENT pDhcpSentOption = (PDML_DHCPCV6_SENT)pCxtLink->hContext; + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "Tag", TRUE) ) + { + /* save update to backup */ + pDhcpSentOption->Tag = (UCHAR)uValue; + + return TRUE; + } + + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + SentOption1_SetParamStringValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + char* pString + ); + + description: + + This function is called to set string parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + char* pString + The updated string value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +SentOption1_SetParamStringValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + char* pString + ) +{ + PCONTEXT_LINK_OBJECT pCxtLink = (PCONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPCV6_SENT pDhcpSentOption = (PDML_DHCPCV6_SENT)pCxtLink->hContext; + PDHCPCV6_CONTEXT_LINK_OBJECT pCxtDhcpcLink = (PDHCPCV6_CONTEXT_LINK_OBJECT)pCxtLink->hParentTable; + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "Alias", TRUE) ) + { + /* save update to backup */ + AnscCopyString(pCxtDhcpcLink->AliasOfSent, (char*)pDhcpSentOption->Alias); + + AnscCopyString((char*)pDhcpSentOption->Alias, pString); + + return TRUE; + } + else if( AnscEqualString(ParamName, "Value", TRUE) ) + { + /* save update to backup */ + AnscCopyString((char*)pDhcpSentOption->Value, pString); + return TRUE; + } + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + SentOption1_Validate + ( + ANSC_HANDLE hInsContext, + char* pReturnParamName, + ULONG* puLength + ); + + description: + + This function is called to finally commit all the update. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* pReturnParamName, + The buffer (128 bytes) of parameter name if there's a validation. + + ULONG* puLength + The output length of the param name. + + return: TRUE if there's no validation. + +**********************************************************************/ +BOOL +SentOption1_Validate + ( + ANSC_HANDLE hInsContext, + char* pReturnParamName, + ULONG* puLength + ) +{ + PCONTEXT_LINK_OBJECT pCxtLink = (PCONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPCV6_SENT pDhcpSentOption = (PDML_DHCPCV6_SENT)pCxtLink->hContext; + PDHCPCV6_CONTEXT_LINK_OBJECT pCxtDhcpcLink = (PDHCPCV6_CONTEXT_LINK_OBJECT)pCxtLink->hParentTable; + PCONTEXT_LINK_OBJECT pCxtLink2 = NULL; + PDML_DHCPCV6_SENT pDhcpSentOption2 = NULL; + PSINGLE_LINK_ENTRY pSListEntry = NULL; + BOOL bFound = FALSE; + + /* Parent hasn't set, we don't permit child is set.*/ + if ( pCxtDhcpcLink->bNew ) + { +#if COSA_DHCPV6_ROLLBACK_TEST + SentOption1_Rollback(hInsContext); +#endif + return FALSE; + } + + /* This is for alias */ + if ( TRUE ) + { + bFound = FALSE; + pSListEntry = AnscSListGetFirstEntry(&pCxtDhcpcLink->SentOptionList); + while( pSListEntry != NULL) + { + pCxtLink2 = ACCESS_CONTEXT_LINK_OBJECT(pSListEntry); + pSListEntry = AnscSListGetNextEntry(pSListEntry); + + pDhcpSentOption2 = (PDML_DHCPCV6_SENT)pCxtLink2->hContext; + + if( DHCPV6_SENDOPTION_ENTRY_MATCH2((char*)pDhcpSentOption->Alias, pDhcpSentOption2->Alias) ) + { + if ( (ANSC_HANDLE)pCxtLink2 == hInsContext ) + { + continue; + } + + _ansc_strcpy(pReturnParamName, "Alias"); + *puLength = AnscSizeOfString("Alias"); + + bFound = TRUE; + + break; + } + + if ( (pDhcpSentOption->bEnabled && pDhcpSentOption2->bEnabled) && + pDhcpSentOption->Tag == pDhcpSentOption2->Tag) + { + if ( (ANSC_HANDLE)pCxtLink2 == hInsContext ) + { + continue; + } + + _ansc_strcpy(pReturnParamName, "Tag"); + *puLength = AnscSizeOfString("Tag"); + + bFound = TRUE; + + break; + + } + + } + + if ( bFound ) + { +#if COSA_DHCPV6_ROLLBACK_TEST + SentOption1_Rollback(hInsContext); +#endif + return FALSE; + } + } + + /* For other check */ + + + return TRUE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG + SentOption1_Commit + ( + ANSC_HANDLE hInsContext + ); + + description: + + This function is called to finally commit all the update. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: The status of the operation. + +**********************************************************************/ +ULONG +SentOption1_Commit + ( + ANSC_HANDLE hInsContext + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PCONTEXT_LINK_OBJECT pCxtLink = (PCONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPCV6_SENT pDhcpSentOption = (PDML_DHCPCV6_SENT)pCxtLink->hContext; + PDHCPCV6_CONTEXT_LINK_OBJECT pCxtDhcpcLink = (PDHCPCV6_CONTEXT_LINK_OBJECT)pCxtLink->hParentTable; + PDML_DHCPCV6_FULL pDhcpClient = (PDML_DHCPCV6_FULL)pCxtDhcpcLink->hContext; + PWAN_DHCPV6_DATA pDhcpv6 = (PWAN_DHCPV6_DATA)g_pWanMgrBE->hDhcpv6; + + if (pDhcpv6 != NULL) + { + if ( pCxtLink->bNew ) + { + returnStatus = WanMgr_DmlDhcpv6cAddSentOption(NULL, pDhcpClient->Cfg.InstanceNumber, pDhcpSentOption ); + + if ( returnStatus == ANSC_STATUS_SUCCESS ) + { + pCxtLink->bNew = FALSE; + + WanMgr_Dhcpv6RegSetDhcpv6Info(pDhcpv6); + } + else + { + DHCPV6_SENTOPTION_SET_DEFAULTVALUE(pDhcpSentOption); + + if ( pCxtDhcpcLink->AliasOfSent[0] ) + AnscCopyString( (char*)pDhcpSentOption->Alias, pCxtDhcpcLink->AliasOfSent ); + } + } + else + { + returnStatus = WanMgr_DmlDhcpv6cSetSentOption(NULL, pDhcpClient->Cfg.InstanceNumber, pDhcpSentOption); + + if ( returnStatus != ANSC_STATUS_SUCCESS) + { + WanMgr_DmlDhcpv6cGetSentOptionbyInsNum(NULL, pDhcpClient->Cfg.InstanceNumber, pDhcpSentOption); + } + } + + AnscZeroMemory( pCxtDhcpcLink->AliasOfSent, sizeof(pCxtDhcpcLink->AliasOfSent) ); + } + + return returnStatus; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG + SentOption1_Rollback + ( + ANSC_HANDLE hInsContext + ); + + description: + + This function is called to roll back the update whenever there's a + validation found. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: The status of the operation. + +**********************************************************************/ +ULONG +SentOption1_Rollback + ( + ANSC_HANDLE hInsContext + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PCONTEXT_LINK_OBJECT pCxtLink = (PCONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPCV6_SENT pDhcpSentOption = (PDML_DHCPCV6_SENT)pCxtLink->hContext; + PDHCPCV6_CONTEXT_LINK_OBJECT pCxtDhcpcLink = (PDHCPCV6_CONTEXT_LINK_OBJECT)pCxtLink->hParentTable; + PDML_DHCPCV6_FULL pDhcpc = (PDML_DHCPCV6_FULL)pCxtDhcpcLink->hContext; + + if ( pCxtDhcpcLink->AliasOfSent[0] ) + AnscCopyString( (char*)pDhcpSentOption->Alias, pCxtDhcpcLink->AliasOfSent ); + + if ( !pCxtLink->bNew ) + { + WanMgr_DmlDhcpv6cGetSentOptionbyInsNum(NULL, pDhcpc->Cfg.InstanceNumber, pDhcpSentOption); + } + else + { + DHCPV6_SENTOPTION_SET_DEFAULTVALUE(pDhcpSentOption); + } + + AnscZeroMemory( pCxtDhcpcLink->AliasOfSent, sizeof(pCxtDhcpcLink->AliasOfSent) ); + + return returnStatus; +} + +/*********************************************************************** + + APIs for Object: + + DHCPv6.Client.{i}.ReceivedOption.{i}. + + * ReceivedOption_GetEntryCount + * ReceivedOption_GetEntry + * ReceivedOption_IsUpdated + * ReceivedOption_Synchronize + * ReceivedOption_GetParamBoolValue + * ReceivedOption_GetParamIntValue + * ReceivedOption_GetParamUlongValue + * ReceivedOption_GetParamStringValue + +***********************************************************************/ +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG + ReceivedOption_GetEntryCount + ( + ANSC_HANDLE hInsContext + ); + + description: + + This function is called to retrieve the count of the table. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: The count of the table + +**********************************************************************/ +ULONG +ReceivedOption_GetEntryCount + ( + ANSC_HANDLE hInsContext + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PDHCPCV6_CONTEXT_LINK_OBJECT pCxtLink = (PDHCPCV6_CONTEXT_LINK_OBJECT)hInsContext; + + return pCxtLink->NumberOfRecv; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ANSC_HANDLE + ReceivedOption_GetEntry + ( + ANSC_HANDLE hInsContext, + ULONG nIndex, + ULONG* pInsNumber + ); + + description: + + This function is called to retrieve the entry specified by the index. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + ULONG nIndex, + The index of this entry; + + ULONG* pInsNumber + The output instance number; + + return: The handle to identify the entry + +**********************************************************************/ +ANSC_HANDLE +ReceivedOption_GetEntry + ( + ANSC_HANDLE hInsContext, + ULONG nIndex, + ULONG* pInsNumber + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PDHCPCV6_CONTEXT_LINK_OBJECT pCxtLink = (PDHCPCV6_CONTEXT_LINK_OBJECT)hInsContext; + + *pInsNumber = nIndex + 1; + + return (ANSC_HANDLE)&pCxtLink->pRecvEntry[nIndex]; /* return the handle */ +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + ReceivedOption_IsUpdated + ( + ANSC_HANDLE hInsContext + ); + + description: + + This function is checking whether the table is updated or not. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: TRUE or FALSE. + +**********************************************************************/ +BOOL +ReceivedOption_IsUpdated + ( + ANSC_HANDLE hInsContext + ) +{ + PDHCPCV6_CONTEXT_LINK_OBJECT pCxtLink = (PDHCPCV6_CONTEXT_LINK_OBJECT)hInsContext; + BOOL bIsUpdated = TRUE; + + /* + We can use one rough granularity interval to get whole table in case + that the updating is too frequent. + */ + if ( ( AnscGetTickInSeconds() - pCxtLink->PreviousVisitTimeOfRecv ) < COSA_DML_DHCPV6_ACCESS_INTERVAL_CLIENTRECV ) + { + bIsUpdated = FALSE; + } + else + { + pCxtLink->PreviousVisitTimeOfRecv = AnscGetTickInSeconds(); + bIsUpdated = TRUE; + } + + return bIsUpdated; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG + ReceivedOption_Synchronize + ( + ANSC_HANDLE hInsContext + ); + + description: + + This function is called to synchronize the table. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: The status of the operation. + +**********************************************************************/ +ULONG +ReceivedOption_Synchronize + ( + ANSC_HANDLE hInsContext + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PDHCPCV6_CONTEXT_LINK_OBJECT pCxtLink = (PDHCPCV6_CONTEXT_LINK_OBJECT)hInsContext; + PDML_DHCPCV6_RECV pDhcpcRecv = NULL; + ULONG count = 0; + + if ( pCxtLink->pRecvEntry ) + { + AnscFreeMemory(pCxtLink->pRecvEntry); + pCxtLink->pRecvEntry = NULL; + pCxtLink->NumberOfRecv = 0; + } + + returnStatus = WanMgr_DmlDhcpv6cGetReceivedOptionCfg + ( + NULL, + pCxtLink->InstanceNumber, + &pDhcpcRecv, + &count + ); + + if ( returnStatus == ANSC_STATUS_SUCCESS ) + { + pCxtLink->pRecvEntry = pDhcpcRecv; + pCxtLink->NumberOfRecv = count; + } + + return returnStatus; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + ReceivedOption_GetParamBoolValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + BOOL* pBool + ); + + description: + + This function is called to retrieve Boolean parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + BOOL* pBool + The buffer of returned boolean value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +ReceivedOption_GetParamBoolValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + BOOL* pBool + ) +{ + /* check the parameter name and return the corresponding value */ + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + UNREFERENCED_PARAMETER(hInsContext); + UNREFERENCED_PARAMETER(ParamName); + UNREFERENCED_PARAMETER(pBool); + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + ReceivedOption_GetParamIntValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + int* pInt + ); + + description: + + This function is called to retrieve integer parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + int* pInt + The buffer of returned integer value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +ReceivedOption_GetParamIntValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + int* pInt + ) +{ + /* check the parameter name and return the corresponding value */ + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + UNREFERENCED_PARAMETER(hInsContext); + UNREFERENCED_PARAMETER(ParamName); + UNREFERENCED_PARAMETER(pInt); + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + ReceivedOption_GetParamUlongValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + ULONG* puLong + ); + + description: + + This function is called to retrieve ULONG parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + ULONG* puLong + The buffer of returned ULONG value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +ReceivedOption_GetParamUlongValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + ULONG* puLong + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PDML_DHCPCV6_RECV pDhcpcRecv = (PDML_DHCPCV6_RECV)hInsContext; + + /* check the parameter name and return the corresponding value */ + if( AnscEqualString(ParamName, "Tag", TRUE) ) + { + /* collect value */ + *puLong = pDhcpcRecv->Tag; + + return TRUE; + } + + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG + ReceivedOption_GetParamStringValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + char* pValue, + ULONG* pUlSize + ); + + description: + + This function is called to retrieve string parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + char* pValue, + The string value buffer; + + ULONG* pUlSize + The buffer of length of string value; + Usually size of 1023 will be used. + If it's not big enough, put required size here and return 1; + + return: 0 if succeeded; + 1 if short of buffer size; (*pUlSize = required size) + -1 if not supported. + +**********************************************************************/ +ULONG +ReceivedOption_GetParamStringValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + char* pValue, + ULONG* pUlSize + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PDML_DHCPCV6_RECV pDhcpcRecv = (PDML_DHCPCV6_RECV)hInsContext; + + /* check the parameter name and return the corresponding value */ + if( AnscEqualString(ParamName, "Value", TRUE) ) + { + /* collect value */ + if ( AnscSizeOfString((const char*)pDhcpcRecv->Value) < *pUlSize) + { + AnscCopyString(pValue, (char*)pDhcpcRecv->Value); + return 0; + } + else + { + *pUlSize = AnscSizeOfString((const char*)pDhcpcRecv->Value)+1; + return 1; + } + } + else if( AnscEqualString(ParamName, "Server", TRUE) ) + { + /* collect value */ + if ( AnscSizeOfString((const char*)pDhcpcRecv->Server) < *pUlSize) + { + AnscCopyString(pValue, (char*)pDhcpcRecv->Server); + return 0; + } + else + { + *pUlSize = AnscSizeOfString((const char*)pDhcpcRecv->Server)+1; + return 1; + } + } + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return -1; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + dhcp6c_mapt_mape_GetParamBoolValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + BOOL* pBool + ); + + description: + + This function is called to retrieve Boolean parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + BOOL* pBool + The buffer of returned boolean value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +dhcp6c_mapt_mape_GetParamBoolValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + BOOL* pBool + ) +{ + UNREFERENCED_PARAMETER(hInsContext); + /* check the parameter name and return the corresponding value */ + if( AnscEqualString(ParamName, "MapIsFMR", TRUE) ) + { +#ifdef _HUB4_PRODUCT_REQ_ + char temp[32] = {0}; + sysevent_get(sysevent_fd, sysevent_token,SYSEVENT_MAP_IS_FMR, temp, sizeof(temp)); + if( AnscEqualString(temp, "TRUE", TRUE)) + *pBool = TRUE; + else + *pBool = FALSE; +#else + *pBool = FALSE; +#endif + return TRUE; + } + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + dhcp6c_mapt_mape_GetParamUlongValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + ULONG* puLong + ); + + description: + + This function is called to retrieve ULONG parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + ULONG* puLong + The buffer of returned ULONG value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL +dhcp6c_mapt_mape_GetParamUlongValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + ULONG* puLong + ) +{ + UNREFERENCED_PARAMETER(hInsContext); +#ifdef _HUB4_PRODUCT_REQ_ + char temp[64] = {0}; +#endif + /* check the parameter name and return the corresponding value */ + if( AnscEqualString(ParamName, "MapEALen", TRUE) ) + { +#ifdef _HUB4_PRODUCT_REQ_ + sysevent_get(sysevent_fd, sysevent_token, SYSEVENT_MAP_EA_LEN, temp, sizeof(temp)); + *puLong = strtoul(temp, NULL, 10); +#else + *puLong = 0; +#endif + return TRUE; + } + + if( AnscEqualString(ParamName, "MapPSIDOffset", TRUE) ) + { +#ifdef _HUB4_PRODUCT_REQ_ + sysevent_get(sysevent_fd, sysevent_token, SYSEVENT_MAPT_PSID_OFFSET, temp, sizeof(temp)); + *puLong = strtoul(temp, NULL, 10); +#else + *puLong = 0; +#endif + return TRUE; + } + + if( AnscEqualString(ParamName, "MapPSIDLen", TRUE) ) + { +#ifdef _HUB4_PRODUCT_REQ_ + sysevent_get(sysevent_fd, sysevent_token, SYSEVENT_MAPT_PSID_LENGTH, temp, sizeof(temp)); + *puLong = strtoul(temp, NULL, 10); +#else + *puLong = 0; +#endif + return TRUE; + } + + if( AnscEqualString(ParamName, "MapPSID", TRUE) ) + { +#ifdef _HUB4_PRODUCT_REQ_ + sysevent_get(sysevent_fd, sysevent_token, SYSEVENT_MAPT_PSID_VALUE, temp, sizeof(temp)); + *puLong = strtoul(temp, NULL, 10); +#else + *puLong = 0; +#endif + return TRUE; + } + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG + dhcp6c_mapt_mape_GetParamStringValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + char* pValue, + ULONG* pUlSize + ); + + description: + + This function is called to retrieve string parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + char* pValue, + The string value buffer; + + ULONG* pUlSize + The buffer of length of string value; + Usually size of 1023 will be used. + If it's not big enough, put required size here and return 1; + + return: 0 if succeeded; + 1 if short of buffer size; (*pUlSize = required size) + -1 if not supported. + +**********************************************************************/ +ULONG +dhcp6c_mapt_mape_GetParamStringValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + char* pValue, + ULONG* pUlSize + ) +{ + UNREFERENCED_PARAMETER(hInsContext); +#ifdef _HUB4_PRODUCT_REQ_ + char temp[64] = {0}; +#endif + UNREFERENCED_PARAMETER(pUlSize); + /* check the parameter name and return the corresponding value */ + if( AnscEqualString(ParamName, "MapTransportMode", TRUE) ) + { +#ifdef _HUB4_PRODUCT_REQ_ + sysevent_get(sysevent_fd, sysevent_token, SYSEVENT_MAP_TRANSPORT_MODE, temp, sizeof(temp)); + if ( AnscSizeOfString(temp) < *pUlSize) + { + AnscCopyString(pValue, temp); + return 0; + } + else + { + *pUlSize = AnscSizeOfString(temp)+1; + return 1; + } +#else + AnscCopyString(pValue, ""); + return 0; +#endif + } + + if( AnscEqualString(ParamName, "MapBRPrefix", TRUE) ) + { +#ifdef _HUB4_PRODUCT_REQ_ + sysevent_get(sysevent_fd, sysevent_token, SYSEVENT_MAP_BR_IPV6_PREFIX, temp, sizeof(temp)); + if ( AnscSizeOfString(temp) < *pUlSize) + { + AnscCopyString(pValue, temp); + return 0; + } + else + { + *pUlSize = AnscSizeOfString(temp)+1; + return 1; + } +#else + AnscCopyString(pValue, ""); + return 0; +#endif + } + + if( AnscEqualString(ParamName, "MapRuleIPv4Prefix", TRUE) ) + { +#ifdef _HUB4_PRODUCT_REQ_ + sysevent_get(sysevent_fd, sysevent_token, SYSEVENT_MAP_RULE_IPADDRESS, temp, sizeof(temp)); + if ( AnscSizeOfString(temp) < *pUlSize) + { + AnscCopyString(pValue, temp); + return 0; + } + else + { + *pUlSize = AnscSizeOfString(temp)+1; + return 1; + } +#else + AnscCopyString(pValue, ""); + return 0; +#endif + } + + if( AnscEqualString(ParamName, "MapRuleIPv6Prefix", TRUE) ) + { +#ifdef _HUB4_PRODUCT_REQ_ + sysevent_get(sysevent_fd, sysevent_token, SYSEVENT_MAP_RULE_IPV6_ADDRESS, temp, sizeof(temp)); + if ( AnscSizeOfString(temp) < *pUlSize) + { + AnscCopyString(pValue, temp); + return 0; + } + else + { + *pUlSize = AnscSizeOfString(temp)+1; + return 1; + } +#else + AnscCopyString(pValue, ""); + return 0; +#endif + } + + if( AnscEqualString(ParamName, "MapIpv4Address", TRUE) ) + { +#ifdef _HUB4_PRODUCT_REQ_ + sysevent_get(sysevent_fd, sysevent_token, SYSEVENT_MAPT_IPADDRESS, temp, sizeof(temp)); + if ( AnscSizeOfString(temp) < *pUlSize) + { + AnscCopyString(pValue, temp); + return 0; + } + else + { + *pUlSize = AnscSizeOfString(temp)+1; + return 1; + } +#else + AnscCopyString(pValue, ""); + return 0; +#endif + } + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return -1; +} diff --git a/source/TR-181/middle_layer_src/wanmgr_dml_dhcpv6.h b/source/TR-181/middle_layer_src/wanmgr_dml_dhcpv6.h new file mode 100644 index 00000000..22c412a4 --- /dev/null +++ b/source/TR-181/middle_layer_src/wanmgr_dml_dhcpv6.h @@ -0,0 +1,507 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2015 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +/********************************************************************** + Copyright [2014] [Cisco Systems, Inc.] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +**********************************************************************/ + +#ifndef _DHCPV6_DML_H +#define _DHCPV6_DML_H + +#include "wanmgr_apis.h" +/*********************************************************************** + + APIs for Object: + + DHCPv6. + + * DHCPv6_GetParamBoolValue + * DHCPv6_GetParamIntValue + * DHCPv6_GetParamUlongValue + * DHCPv6_GetParamStringValue + +***********************************************************************/ +BOOL +DHCPv6_GetParamBoolValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + BOOL* pBool + ); + +BOOL +DHCPv6_GetParamIntValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + int* pInt + ); + +BOOL +DHCPv6_GetParamUlongValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + ULONG* pUlong + ); + +ULONG +DHCPv6_GetParamStringValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + char* pValue, + ULONG* pUlSize + ); + +/*********************************************************************** + + APIs for Object: + + DHCPv6.Client.{i}. + + * Client3_GetEntryCount + * Client3_GetEntry + * Client3_AddEntry + * Client3_DelEntry + * Client3_GetParamBoolValue + * Client3_GetParamIntValue + * Client3_GetParamUlongValue + * Client3_GetParamStringValue + * Client3_SetParamBoolValue + * Client3_SetParamIntValue + * Client3_SetParamUlongValue + * Client3_SetParamStringValue + * Client3_Validate + * Client3_Commit + * Client3_Rollback + +***********************************************************************/ +ULONG +Client3_GetEntryCount + ( + ANSC_HANDLE + ); + +ANSC_HANDLE +Client3_GetEntry + ( + ANSC_HANDLE hInsContext, + ULONG nIndex, + ULONG* pInsNumber + ); + +ANSC_HANDLE +Client3_AddEntry + ( + ANSC_HANDLE hInsContext, + ULONG* pInsNumber + ); + +ULONG +Client3_DelEntry + ( + ANSC_HANDLE hInsContext, + ANSC_HANDLE hInstance + ); + +BOOL +Client3_GetParamBoolValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + BOOL* pBool + ); + +BOOL +Client3_GetParamIntValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + int* pInt + ); + +BOOL +Client3_GetParamUlongValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + ULONG* pUlong + ); + +ULONG +Client3_GetParamStringValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + char* pValue, + ULONG* pUlSize + ); + +BOOL +Client3_SetParamBoolValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + BOOL bValue + ); + +BOOL +Client3_SetParamIntValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + int value + ); + +BOOL +Client3_SetParamUlongValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + ULONG uValuepUlong + ); + +BOOL +Client3_SetParamStringValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + char* strValue + ); + +BOOL +Client3_Validate + ( + ANSC_HANDLE hInsContext, + char* pReturnParamName, + ULONG* puLength + ); + +ULONG +Client3_Commit + ( + ANSC_HANDLE hInsContext + ); + +ULONG +Client3_Rollback + ( + ANSC_HANDLE hInsContext + ); + +/*********************************************************************** + + APIs for Object: + + DHCPv6.Client.{i}.Server.{i}. + + * Server2_GetEntryCount + * Server2_GetEntry + * Server2_IsUpdated + * Server2_Synchronize + * Server2_GetParamBoolValue + * Server2_GetParamIntValue + * Server2_GetParamUlongValue + * Server2_GetParamStringValue + +***********************************************************************/ +ULONG +Server2_GetEntryCount + ( + ANSC_HANDLE + ); + +ANSC_HANDLE +Server2_GetEntry + ( + ANSC_HANDLE hInsContext, + ULONG nIndex, + ULONG* pInsNumber + ); + +BOOL +Server2_IsUpdated + ( + ANSC_HANDLE hInsContext + ); + +ULONG +Server2_Synchronize + ( + ANSC_HANDLE hInsContext + ); + +BOOL +Server2_GetParamBoolValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + BOOL* pBool + ); + +BOOL +Server2_GetParamIntValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + int* pInt + ); + +BOOL +Server2_GetParamUlongValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + ULONG* pUlong + ); + +ULONG +Server2_GetParamStringValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + char* pValue, + ULONG* pUlSize + ); + +/*********************************************************************** + + APIs for Object: + + DHCPv6.Client.{i}.SentOption.{i}. + + * SentOption1_GetEntryCount + * SentOption1_GetEntry + * SentOption1_AddEntry + * SentOption1_DelEntry + * SentOption1_GetParamBoolValue + * SentOption1_GetParamIntValue + * SentOption1_GetParamUlongValue + * SentOption1_GetParamStringValue + * SentOption1_SetParamBoolValue + * SentOption1_SetParamIntValue + * SentOption1_SetParamUlongValue + * SentOption1_SetParamStringValue + * SentOption1_Validate + * SentOption1_Commit + * SentOption1_Rollback + +***********************************************************************/ +ULONG +SentOption1_GetEntryCount + ( + ANSC_HANDLE + ); + +ANSC_HANDLE +SentOption1_GetEntry + ( + ANSC_HANDLE hInsContext, + ULONG nIndex, + ULONG* pInsNumber + ); + +ANSC_HANDLE +SentOption1_AddEntry + ( + ANSC_HANDLE hInsContext, + ULONG* pInsNumber + ); + +ULONG +SentOption1_DelEntry + ( + ANSC_HANDLE hInsContext, + ANSC_HANDLE hInstance + ); + +BOOL +SentOption1_GetParamBoolValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + BOOL* pBool + ); + +BOOL +SentOption1_GetParamIntValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + int* pInt + ); + +BOOL +SentOption1_GetParamUlongValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + ULONG* pUlong + ); + +ULONG +SentOption1_GetParamStringValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + char* pValue, + ULONG* pUlSize + ); + +BOOL +SentOption1_SetParamBoolValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + BOOL bValue + ); + +BOOL +SentOption1_SetParamIntValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + int value + ); + +BOOL +SentOption1_SetParamUlongValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + ULONG uValuepUlong + ); + +BOOL +SentOption1_SetParamStringValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + char* strValue + ); + +BOOL +SentOption1_Validate + ( + ANSC_HANDLE hInsContext, + char* pReturnParamName, + ULONG* puLength + ); + +ULONG +SentOption1_Commit + ( + ANSC_HANDLE hInsContext + ); + +ULONG +SentOption1_Rollback + ( + ANSC_HANDLE hInsContext + ); + +/*********************************************************************** + + APIs for Object: + + DHCPv6.Client.{i}.ReceivedOption.{i}. + + * ReceivedOption_GetEntryCount + * ReceivedOption_GetEntry + * ReceivedOption_IsUpdated + * ReceivedOption_Synchronize + * ReceivedOption_GetParamBoolValue + * ReceivedOption_GetParamIntValue + * ReceivedOption_GetParamUlongValue + * ReceivedOption_GetParamStringValue + +***********************************************************************/ +ULONG +ReceivedOption_GetEntryCount + ( + ANSC_HANDLE + ); + +ANSC_HANDLE +ReceivedOption_GetEntry + ( + ANSC_HANDLE hInsContext, + ULONG nIndex, + ULONG* pInsNumber + ); + +BOOL +ReceivedOption_IsUpdated + ( + ANSC_HANDLE hInsContext + ); + +ULONG +ReceivedOption_Synchronize + ( + ANSC_HANDLE hInsContext + ); + +BOOL +ReceivedOption_GetParamBoolValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + BOOL* pBool + ); + +BOOL +ReceivedOption_GetParamIntValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + int* pInt + ); + +BOOL +ReceivedOption_GetParamUlongValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + ULONG* pUlong + ); + +ULONG +ReceivedOption_GetParamStringValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + char* pValue, + ULONG* pUlSize + ); + +#endif diff --git a/source/TR-181/middle_layer_src/wanmgr_dml_iface_apis.c b/source/TR-181/middle_layer_src/wanmgr_dml_iface_apis.c new file mode 100644 index 00000000..16440ab6 --- /dev/null +++ b/source/TR-181/middle_layer_src/wanmgr_dml_iface_apis.c @@ -0,0 +1,3930 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2019 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +/********************************************************************** + Copyright [2014] [Cisco Systems, Inc.] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +**********************************************************************/ + +#include "wanmgr_dml_iface_apis.h" +#include "wanmgr_rdkbus_apis.h" +#include "wanmgr_net_utils.h" +#include "wanmgr_dhcpv4_apis.h" +#include "wanmgr_dhcpv6_apis.h" +#include "wanmgr_data.h" + +/*********************************************************************** + + APIs for Object: + + X_RDK_WanManager.CPEInterface. + + * WanIf_GetEntryCount + * WanIf_GetEntry + * WanIf_GetParamStringValue + * WanIf_SetParamStringValue + * WanIf_Validate + * WanIf_Commit + * WanIf_Rollback + +***********************************************************************/ +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG WanIf_GetEntryCount(ANSC_HANDLE hInsContext); + + description: + + This function is called to retrieve the count of the table. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: The count of the table + +**********************************************************************/ +ULONG WanIf_GetEntryCount(ANSC_HANDLE hInsContext) +{ + ULONG count = 0; + + WanMgr_IfaceCtrl_Data_t* pWanDmlIfaceCtrl = WanMgr_GetIfaceCtrl_locked(); + if(pWanDmlIfaceCtrl != NULL) + { + count = pWanDmlIfaceCtrl->ulTotalNumbWanInterfaces; + + WanMgrDml_GetIfaceCtrl_release(pWanDmlIfaceCtrl); + } + + return count; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ANSC_HANDLE WanIf_GetEntry(ANSC_HANDLE hInsContext, ULONG nIndex, ULONG* pInsNumber); + + description: + + This function is called to retrieve the entry specified by the index. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + ULONG nIndex, + The index of this entry; + + ULONG* pInsNumber + The output instance number; + + return: The handle to identify the entry + +**********************************************************************/ +ANSC_HANDLE WanIf_GetEntry(ANSC_HANDLE hInsContext, ULONG nIndex, ULONG* pInsNumber) +{ + ANSC_HANDLE pDmlEntry = NULL; + + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(nIndex); + if(pWanDmlIfaceData != NULL) + { + *pInsNumber = nIndex + 1; + pDmlEntry = (ANSC_HANDLE) pWanDmlIfaceData; + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + + return pDmlEntry; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG WanIf_GetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pValue, ULONG* pUlSize); + + description: + + This function is called to retrieve string parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + char* pValue, + The string value buffer; + + ULONG* pUlSize + The buffer of length of string value; + Usually size of 1023 will be used. + If it's not big enough, put required size here and return 1; + + return: 0 if succeeded; + 1 if short of buffer size; (*pUlSize = required size) + -1 if not supported. + +**********************************************************************/ +ULONG WanIf_GetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pValue, ULONG* pUlSize) +{ + ULONG ret = -1; + + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + + ///* check the parameter name and return the corresponding value */ + if( AnscEqualString(ParamName, "Name", TRUE) ) + { + /* collect value */ + if ( ( sizeof( pWanDmlIface->Name ) - 1 ) < *pUlSize ) + { + AnscCopyString( pValue, pWanDmlIface->Name ); + ret = 0; + } + else + { + *pUlSize = sizeof( pWanDmlIface->Name ); + ret = 1; + } + } + else if( AnscEqualString(ParamName, "DisplayName", TRUE) ) + { + /* collect value */ + if ( ( sizeof( pWanDmlIface->DisplayName ) - 1 ) < *pUlSize ) + { + AnscCopyString( pValue, pWanDmlIface->DisplayName ); + ret = 0; + } + else + { + *pUlSize = sizeof( pWanDmlIface->DisplayName ); + ret = 1; + } + } + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + + return ret; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL WanIf_SetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pString); + + description: + + This function is called to set string parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + char* pString + The updated string value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL WanIf_SetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pString) +{ + BOOL ret = FALSE; + + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "Name", TRUE)) + { + AnscCopyString(pWanDmlIface->Name, pString); + ret = TRUE; + } + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + + return ret; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL WanIf_Validate(ANSC_HANDLE hInsContext, char* pReturnParamName, ULONG* puLength); + + description: + + This function is called to set ULONG parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + ULONG uValue + The updated ULONG value; + + return: TRUE if succeeded. + +**********************************************************************/ + +BOOL WanIf_Validate(ANSC_HANDLE hInsContext, char* pReturnParamName, ULONG* puLength) +{ + return TRUE; +} + +/********************************************************************** + caller: owner of this object + + prototype: + ULONG WanIf_Commit(ANSC_HANDLE hInsContext); + + description: + This function is called to finally commit all the update. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: The status of the operation. +**********************************************************************/ +ULONG WanIf_Commit(ANSC_HANDLE hInsContext) +{ + return 0; +} + +/********************************************************************** + caller: owner of this object + + prototype: + ULONG WanIf_Rollback(ANSC_HANDLE hInsContext); + + description: + This function is called to roll back the update whenever there's a + validation found. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: The status of the operation. +**********************************************************************/ +ULONG WanIf_Rollback(ANSC_HANDLE hInsContext) +{ + return 0; +} + +/*********************************************************************** + + APIs for Object: + + X_RDK_WanManager.CPEInterface.{i}.Wan. + + * WanIfCfg_GetParamUlongValue + * WanIfCfg_SetParamUlongValue + * WanIfCfg_GetParamBoolValue + * WanIfCfg_SetParamBoolValue + * WanIfCfg_GetParamIntValue + * WanIfCfg_SetParamIntValue + * WanIfCfg_Validate + * WanIfCfg_Commit + * WanIfCfg_Rollback + +***********************************************************************/ +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL WanIfCfg_GetParamIntValue(ANSC_HANDLE hInsContext, char* ParamName, int* pInt); + + description: + + This function is called to retrieve integer parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + int* pInt + The buffer of returned ULONG value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL WanIfCfg_GetParamIntValue(ANSC_HANDLE hInsContext, char* ParamName, int* pInt) +{ + BOOL ret = FALSE; + + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "Priority", TRUE)) + { + *pInt = pWanDmlIface->Wan.Priority; + ret = TRUE; + } + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + + return ret; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL WanIfCfg_SetParamIntValue(ANSC_HANDLE hInsContext, char* ParamName, int iValue); + + description: + + This function is called to set ULONG parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + int iValue + The updated int value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL WanIfCfg_SetParamIntValue(ANSC_HANDLE hInsContext, char* ParamName, int iValue) +{ + BOOL ret = FALSE; + UINT uiTotalIfaces = -1; + INT IfIndex = 0; + BOOL Status = FALSE; + DML_WAN_IFACE_TYPE priorityType = WAN_IFACE_TYPE_UNCONFIGURED; + + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + IfIndex = pWanDmlIface->uiIfaceIdx; + priorityType = pWanDmlIface->Wan.Type; + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "Priority", TRUE)) + { + uiTotalIfaces = WanIf_GetEntryCount(NULL); + + if ( WanManager_CheckGivenPriorityExists(IfIndex, uiTotalIfaces, iValue, priorityType, &Status) == ANSC_STATUS_SUCCESS ) + { + if(Status) + { + CcspTraceError(("%s Another interface with same type is already exists with given priority \n", __FUNCTION__)); + return FALSE; + } + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + pWanDmlIface->Wan.Priority = iValue; + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + return TRUE; + } + } + } + } + } + + return ret; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL WanIfCfg_GetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG* puLong); + + description: + + This function is called to retrieve ULONG parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + ULONG* puLong + The buffer of returned ULONG value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL WanIfCfg_GetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG* puLong) +{ + BOOL ret = FALSE; + + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + + /* check the parameter name and return the corresponding value */ + if( AnscEqualString(ParamName, "SelectionTimeout", TRUE)) + { + *puLong = pWanDmlIface->Wan.SelectionTimeout; + ret = TRUE; + } + if( AnscEqualString(ParamName, "Status", TRUE)) + { + *puLong = pWanDmlIface->Wan.Status; + ret = TRUE; + } + if( AnscEqualString(ParamName, "Type", TRUE)) + { + *puLong = pWanDmlIface->Wan.Type; + ret = TRUE; + } + if( AnscEqualString(ParamName, "Priority", TRUE)) + { + *puLong = pWanDmlIface->Wan.Priority; + ret = TRUE; + } + if( AnscEqualString(ParamName, "LinkStatus", TRUE)) + { + *puLong = pWanDmlIface->Wan.LinkStatus; + ret = TRUE; + } + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + + return ret; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL WanIfCfg_SetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG uValue); + + description: + + This function is called to set ULONG parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + ULONG uValue + The updated ULONG value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL WanIfCfg_SetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG uValue) +{ + BOOL ret = FALSE; + UINT uiTotalIfaces = -1; + INT IfIndex = 0; + INT priority; + BOOL Status = FALSE; + + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "SelectionTimeout", TRUE)) + { + pWanDmlIface->Wan.SelectionTimeout = uValue; + ret = TRUE; + } + if( AnscEqualString(ParamName, "Type", TRUE)) + { + IfIndex = pWanDmlIface->uiIfaceIdx; + priority = pWanDmlIface->Wan.Priority; + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + uiTotalIfaces = WanIf_GetEntryCount(NULL); + if ( WanManager_CheckGivenTypeExists(IfIndex, uiTotalIfaces, uValue, priority, &Status) == ANSC_STATUS_SUCCESS ) + { + if(Status) + { + CcspTraceError(("%s Another interface with same type and priority already exists\n", __FUNCTION__)); + return FALSE; + } + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + pWanDmlIface->Wan.Type = uValue; + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + return TRUE; + } + return FALSE; + } + } + if( AnscEqualString(ParamName, "LinkStatus", TRUE)) + { + pWanDmlIface->Wan.LinkStatus = uValue; + ret = TRUE; + } + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + + return ret; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL WanIfCfg_GetParamBoolValue(ANSC_HANDLE hInsContext, char* ParamName, BOOL* pBool); + + description: + + This function is called to retrieve Boolean parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + BOOL* pBool + The buffer of returned boolean value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL WanIfCfg_GetParamBoolValue(ANSC_HANDLE hInsContext, char* ParamName, BOOL* pBool) +{ + BOOL ret = FALSE; + + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + + //* check the parameter name and return the corresponding value */ + if( AnscEqualString(ParamName, "Enable", TRUE)) + { + *pBool = pWanDmlIface->Wan.Enable; + ret = TRUE; + } + if( AnscEqualString(ParamName, "Refresh", TRUE)) + { + *pBool = pWanDmlIface->Wan.Refresh; + ret = TRUE; + } + if( AnscEqualString(ParamName, "ActiveLink", TRUE)) + { + *pBool = pWanDmlIface->Wan.ActiveLink; + ret = TRUE; + } + if( AnscEqualString(ParamName, "EnableDSLite", TRUE)) + { + *pBool = pWanDmlIface->Wan.EnableDSLite; + ret = TRUE; + } + if( AnscEqualString(ParamName, "EnableIPoEHealthCheck", TRUE)) + { + *pBool = pWanDmlIface->Wan.EnableIPoE; + ret = TRUE; + } + if( AnscEqualString(ParamName, "EnableMAPT", TRUE)) + { + *pBool = pWanDmlIface->Wan.EnableMAPT; + ret = TRUE; + } + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + + return ret; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL WanIfCfg_SetParamBoolValue(ANSC_HANDLE hInsContext, char* ParamName, BOOL bValue); + + description: + + This function is called to set BOOL parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + BOOL bValue + The updated BOOL value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL WanIfCfg_SetParamBoolValue(ANSC_HANDLE hInsContext, char* ParamName, BOOL bValue) +{ + BOOL ret = FALSE; + + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "Enable", TRUE)) + { + pWanDmlIface->Wan.Enable = bValue; + ret = TRUE; + } + if( AnscEqualString(ParamName, "Refresh", TRUE)) + { + pWanDmlIface->Wan.Refresh = bValue; + ret = TRUE; + } + if( AnscEqualString(ParamName, "ActiveLink", TRUE)) + { + pWanDmlIface->Wan.ActiveLink = bValue; + ret = TRUE; + } + if( AnscEqualString(ParamName, "EnableDSLite", TRUE)) + { + pWanDmlIface->Wan.EnableDSLite = bValue; + ret = TRUE; + } + if( AnscEqualString(ParamName, "EnableIPoEHealthCheck", TRUE)) + { + pWanDmlIface->Wan.EnableIPoE = bValue; + ret = TRUE; + } + if( AnscEqualString(ParamName, "EnableMAPT", TRUE)) + { + pWanDmlIface->Wan.EnableMAPT = bValue; + ret = TRUE; + } + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + + return ret; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG WanIfCfg_GetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pValue, ULONG* pUlSize); + + description: + + This function is called to retrieve string parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + char* pValue, + The string value buffer; + + ULONG* pUlSize + The buffer of length of string value; + Usually size of 1023 will be used. + If it's not big enough, put required size here and return 1; + + return: 0 if succeeded; + 1 if short of buffer size; (*pUlSize = required size) + -1 if not supported. + +**********************************************************************/ +ULONG WanIfCfg_GetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pValue, ULONG* pUlSize) +{ + ULONG ret = -1; + + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + + /* collect value */ + if ( ( sizeof( pWanDmlIface->Wan.Name ) - 1 ) < *pUlSize ) + { + AnscCopyString( pValue, pWanDmlIface->Wan.Name ); + ret = 0; + } + else + { + *pUlSize = sizeof( pWanDmlIface->Wan.Name ); + ret = 1; + } + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + + return ret; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL WanIfCfg_SetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pString); + + description: + + This function is called to set string parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + char* pString + The updated string value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL WanIfCfg_SetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pString) +{ + BOOL ret = FALSE; + + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "Name", TRUE)) + { + AnscCopyString(pWanDmlIface->Wan.Name, pString); + ret = TRUE; + } + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + + return ret; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL WanIfCfg_Validate(ANSC_HANDLE hInsContext, char* pReturnParamName, ULONG* puLength); + + description: + + This function is called to set ULONG parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + ULONG uValue + The updated ULONG value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL WanIfCfg_Validate(ANSC_HANDLE hInsContext, char* pReturnParamName, ULONG* puLength) +{ + return TRUE; +} + +/********************************************************************** + caller: owner of this object + + prototype: + ULONG WanIfCfg_Commit(ANSC_HANDLE hInsContext); + + description: + This function is called to finally commit all the update. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: The status of the operation. +**********************************************************************/ +ULONG WanIfCfg_Commit(ANSC_HANDLE hInsContext) +{ + ULONG ret = -1; + + ANSC_STATUS result; + + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + + result = DmlSetWanIfCfg( pWanDmlIface->uiInstanceNumber, pWanDmlIface ); + if(result != ANSC_STATUS_SUCCESS) + { + AnscTraceError(("%s: Failed \n", __FUNCTION__)); + } + else + { + ret = 0; + } + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + + return ret; +} + +/********************************************************************** + caller: owner of this object + + prototype: + ULONG WanIfCfg_Rollback(ANSC_HANDLE hInsContext); + + description: + This function is called to roll back the update whenever there's a + validation found. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: The status of the operation. +**********************************************************************/ +ULONG WanIfCfg_Rollback(ANSC_HANDLE hInsContext) +{ + return TRUE; +} + +/*********************************************************************** + + APIs for Object: + + X_RDK_WanManager.CPEInterface.{i}.Wan.Validaton + + * WanIfValidation_GetParamBoolValue + * WanIfValidation_SetParamBoolValue + * WanIfValidation_Validate + * WanIfValidation_Commit + * WanIfValidation_Rollback +***********************************************************************/ +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL WanIfValidation_GetParamBoolValue(ANSC_HANDLE hInsContext, char* ParamName, BOOL* pBool); + + description: + + This function is called to retrieve Boolean parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + BOOL* pBool + The buffer of returned boolean value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL WanIfValidation_GetParamBoolValue(ANSC_HANDLE hInsContext, char* ParamName, BOOL* pBool) +{ + BOOL ret = FALSE; + + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + + /* check the parameter name and return the corresponding value */ + if( AnscEqualString(ParamName, "Discovery-Offer", TRUE)) + { + *pBool = pWanDmlIface->Wan.Validation.DiscoverOffer; + ret = TRUE; + } + if( AnscEqualString(ParamName, "Solicit-Advertise", TRUE)) + { + *pBool = pWanDmlIface->Wan.Validation.SolicitAdvertise; + ret = TRUE; + } + if( AnscEqualString(ParamName, "RS-RA", TRUE)) + { + *pBool = pWanDmlIface->Wan.Validation.RS_RA; + ret = TRUE; + } + if( AnscEqualString(ParamName, "PADI-PADO", TRUE)) + { + *pBool = pWanDmlIface->Wan.Validation.PadiPado; + ret = TRUE; + } + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + + return ret; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL WanIfValidation_SetParamBoolValue(ANSC_HANDLE hInsContext, char* ParamName, BOOL bValue); + + description: + + This function is called to set BOOL parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + BOOL bValue + The updated BOOL value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL WanIfValidation_SetParamBoolValue(ANSC_HANDLE hInsContext, char* ParamName, BOOL bValue) +{ + BOOL ret = FALSE; + + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "Discovery-Offer", TRUE)) + { + pWanDmlIface->Wan.Validation.DiscoverOffer = bValue; + ret = TRUE; + } + if( AnscEqualString(ParamName, "Solicit-Advertise", TRUE)) + { + pWanDmlIface->Wan.Validation.SolicitAdvertise = bValue; + ret = TRUE; + } + if( AnscEqualString(ParamName, "RS-RA", TRUE)) + { + pWanDmlIface->Wan.Validation.RS_RA = bValue; + ret = TRUE; + } + if( AnscEqualString(ParamName, "PADI-PADO", TRUE)) + { + pWanDmlIface->Wan.Validation.PadiPado = bValue; + ret = TRUE; + } + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + + return ret; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL WanIfValidation_Validate(ANSC_HANDLE hInsContext, char* pReturnParamName, ULONG* puLength); + + description: + + This function is called to set ULONG parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + ULONG uValue + The updated ULONG value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL WanIfValidation_Validate(ANSC_HANDLE hInsContext, char* pReturnParamName, ULONG* puLength) +{ + return TRUE; +} + +/********************************************************************** + caller: owner of this object + + prototype: + ULONG WanIfValidation_Commit(ANSC_HANDLE hInsContext); + + description: + This function is called to finally commit all the update. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: The status of the operation. +**********************************************************************/ +ULONG WanIfValidation_Commit(ANSC_HANDLE hInsContext) +{ + ULONG ret = -1; + + + ANSC_STATUS result = ANSC_STATUS_SUCCESS; + + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + + /* check the parameter name and set the corresponding value */ + result = DmlSetWanIfValidationCfg(pWanDmlIface->uiInstanceNumber, pWanDmlIface); + if (result != ANSC_STATUS_SUCCESS) + { + AnscTraceError(("%s: Failed \n", __FUNCTION__)); + } + else + { + ret = 0; + } + + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + + return ret; +} + +/********************************************************************** + caller: owner of this object + + prototype: + ULONG WanIfValidation_Rollback(ANSC_HANDLE hInsContext); + + description: + This function is called to roll back the update whenever there's a + validation found. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: The status of the operation. +**********************************************************************/ +ULONG WanIfValidation_Rollback(ANSC_HANDLE hInsContext) +{ + return 0; +} + +/*********************************************************************** + + APIs for Object: + + X_RDK_WanManager.CPEInterface.{i}.Phy. + + * WanIfPhy_GetParamStringValue + * WanIfPhy_SetParamStringValue + * WanIfPhy_GetParamUlongValue + * WanIfPhy_SetParamUlongValue + * WanIfPhy_Validate + * WanIfPhy_Commit + * WanIfPhy_Rollback + +***********************************************************************/ + + +ULONG WanIfPhy_GetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pValue, ULONG* pUlSize) +{ + ULONG ret = -1; + + + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "Path", TRUE) ) + { + /* collect value */ + if ( ( sizeof( pWanDmlIface->Phy.Path ) - 1 ) < *pUlSize ) + { + AnscCopyString( pValue, pWanDmlIface->Phy.Path ); + ret = 0; + } + else + { + *pUlSize = sizeof( pWanDmlIface->Phy.Path ); + ret = 1; + } + } + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + + return ret; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL WanIfPhy_SetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pString); + + description: + + This function is called to set string parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + char* pString + The updated string value; + + return: TRUE if succeeded. + +**********************************************************************/ + +BOOL WanIfPhy_SetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pString) +{ + + BOOL ret = FALSE; + + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "Path", TRUE)) + { + AnscCopyString(pWanDmlIface->Phy.Path, pString); + ret = TRUE; + } + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + + return ret; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL WanIfPhy_GetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG* puLong); + + description: + + This function is called to retrieve ULONG parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + ULONG* puLong + The buffer of returned ULONG value; + + return: TRUE if succeeded. + +**********************************************************************/ + +BOOL WanIfPhy_GetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG* puLong) +{ + BOOL ret = FALSE; + + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "Status", TRUE)) + { + *puLong = pWanDmlIface->Phy.Status; + ret = TRUE; + } + + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + + return ret; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL WanIfPhy_SetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG uValue); + + description: + + This function is called to set ULONG parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + ULONG uValue + The updated ULONG value; + + return: TRUE if succeeded. + +**********************************************************************/ + +BOOL WanIfPhy_SetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG uValue) +{ + BOOL ret = FALSE; + + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "Status", TRUE)) + { + pWanDmlIface->Phy.Status = uValue; + ret = TRUE; + } + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + + return ret; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL WanIfPhy_Validate(ANSC_HANDLE hInsContext, char* pReturnParamName, ULONG* puLength); + + description: + + This function is called to set ULONG parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + ULONG uValue + The updated ULONG value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL WanIfPhy_Validate(ANSC_HANDLE hInsContext, char* pReturnParamName, ULONG* puLength) +{ + return TRUE; +} + +/********************************************************************** + caller: owner of this object + + prototype: + ULONG WanIfPhy_Commit(ANSC_HANDLE hInsContext); + + description: + This function is called to finally commit all the update. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: The status of the operation. +**********************************************************************/ +ULONG WanIfPhy_Commit(ANSC_HANDLE hInsContext) +{ + return 0; +} + +/********************************************************************** + caller: owner of this object + + prototype: + ULONG WanIfPhy_Rollback(ANSC_HANDLE hInsContext); + + description: + This function is called to roll back the update whenever there's a + validation found. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: The status of the operation. +**********************************************************************/ +ULONG WanIfPhy_Rollback(ANSC_HANDLE hInsContext) +{ + return 0; +} + +/*********************************************************************** + + APIs for Object: + + X_RDK_WanManager.CPEInterface.{i}.DynamicTrigger. + + * WanIfDynTrigger_GetParamUlongValue + * WanIfDynTrigger_GetParamBoolValue + * WanIfDynTrigger_SetParamUlongValue + * WanIfDynTrigger_SetParamBoolValue + * WanIfDynTrigger_Validate + * WanIfDynTrigger_Commit + * WanIfDynTrigger_Rollback + +***********************************************************************/ + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL WanIfDynTrigger_GetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG* puLong); + + description: + + This function is called to retrieve ULONG parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + ULONG* puLong + The buffer of returned ULONG value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL WanIfDynTrigger_GetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG* puLong) +{ + BOOL ret = FALSE; + + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "Delay", TRUE)) + { + *puLong = pWanDmlIface->DynamicTrigger.Delay; + ret = TRUE; + } + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + + return ret; + +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL WanIfDynTrigger_SetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG uValue); + + description: + + This function is called to set ULONG parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + ULONG uValue + The updated ULONG value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL WanIfDynTrigger_SetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG uValue) +{ + BOOL ret = FALSE; + + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "Delay", TRUE)) + { + pWanDmlIface->DynamicTrigger.Delay = uValue; + ret = TRUE; + } + + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + + return ret; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL WanIfDynTrigger_GetParamBoolValue(ANSC_HANDLE hInsContext, char* ParamName, BOOL* pBool); + + description: + + This function is called to retrieve Boolean parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + BOOL* pBool + The buffer of returned boolean value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL WanIfDynTrigger_GetParamBoolValue(ANSC_HANDLE hInsContext, char* ParamName, BOOL* pBool) +{ + BOOL ret = FALSE; + + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "Enable", TRUE)) + { + *pBool = pWanDmlIface->DynamicTrigger.Enable; + ret = TRUE; + } + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + + return ret; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL WanIfDynTrigger_SetParamBoolValue(ANSC_HANDLE hInsContext, char* ParamName, BOOL bValue); + + description: + + This function is called to set BOOL parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + BOOL bValue + The updated BOOL value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL WanIfDynTrigger_SetParamBoolValue(ANSC_HANDLE hInsContext, char* ParamName, BOOL bValue) +{ + BOOL ret = FALSE; + + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "Enable", TRUE)) + { + /* save update to backup */ + pWanDmlIface->DynamicTrigger.Enable = bValue; + ret = TRUE; + } + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + + return ret; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL WanIfDynTrigger_Validate(ANSC_HANDLE hInsContext, char* pReturnParamName, ULONG* puLength); + + description: + + This function is called to set ULONG parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + ULONG uValue + The updated ULONG value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL WanIfDynTrigger_Validate(ANSC_HANDLE hInsContext, char* pReturnParamName, ULONG* puLength) +{ + return TRUE; +} + +/********************************************************************** + caller: owner of this object + + prototype: + ULONG WanIfDynTrigger_Commit(ANSC_HANDLE hInsContext); + + description: + This function is called to finally commit all the update. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: The status of the operation. +**********************************************************************/ +ULONG WanIfDynTrigger_Commit(ANSC_HANDLE hInsContext) +{ + return 0; +} + +/********************************************************************** + caller: owner of this object + + prototype: + ULONG WanIfDynTrigger_Rollback(ANSC_HANDLE hInsContext); + + description: + This function is called to roll back the update whenever there's a + validation found. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: The status of the operation. +**********************************************************************/ +ULONG WanIfDynTrigger_Rollback(ANSC_HANDLE hInsContext) +{ + return 0; +} + +/*********************************************************************** + + APIs for Object: + + X_RDK_WanManager.CPEInterface.{i}.IP. + + * WanIfIpCfg_GetParamUlongValue + * WanIfIpCfg_SetParamUlongValue + * WanIfIpCfg_GetParamStringValue + * WanIfIpCfg_SetParamStringValue + * WanIfIpCfg_Validate + * WanIfIpCfg_Commit + * WanIfIpCfg_Rollback + +***********************************************************************/ + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL WanIfIpCfg_GetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG* puLong); + + description: + + This function is called to retrieve ULONG parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + ULONG* puLong + The buffer of returned ULONG value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL WanIfIpCfg_GetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG* puLong) +{ + BOOL ret = FALSE; + + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "IPv4Status", TRUE)) + { + *puLong = pWanDmlIface->IP.Ipv4Status; + ret = TRUE; + } + if( AnscEqualString(ParamName, "IPv6Status", TRUE)) + { + *puLong = pWanDmlIface->IP.Ipv6Status; + ret = TRUE; + } + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + + return ret; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL WanIfIpCfg_SetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG uValue); + + description: + + This function is called to set ULONG parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + ULONG uValue + The updated ULONG value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL WanIfIpCfg_SetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG uValue) +{ + BOOL ret = FALSE; + + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "IPv4Status", TRUE)) + { + pWanDmlIface->IP.Ipv4Status = uValue; + ret = TRUE; + } + if( AnscEqualString(ParamName, "IPv6Status", TRUE)) + { + pWanDmlIface->IP.Ipv6Status = uValue; + ret = TRUE; + } + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + + return ret; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG WanIfIpCfg_GetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pValue, ULONG* pUlSize); + + description: + + This function is called to retrieve string parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + char* pValue, + The string value buffer; + + ULONG* pUlSize + The buffer of length of string value; + Usually size of 1023 will be used. + If it's not big enough, put required size here and return 1; + + return: 0 if succeeded; + 1 if short of buffer size; (*pUlSize = required size) + -1 if not supported. + +**********************************************************************/ +ULONG WanIfIpCfg_GetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pValue, ULONG* pUlSize) +{ + ULONG ret = -1; + + + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "Path", TRUE) ) + { + /* collect value */ + if ( ( sizeof( pWanDmlIface->IP.Path ) - 1 ) < *pUlSize ) + { + AnscCopyString( pValue, pWanDmlIface->IP.Path ); + ret = 0; + } + else + { + *pUlSize = sizeof( pWanDmlIface->IP.Path ); + ret = 1; + } + } + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + + return ret; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL WanIfIpCfg_SetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pString); + + description: + + This function is called to set string parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + char* pString + The updated string value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL WanIfIpCfg_SetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pString) +{ + BOOL ret = FALSE; + + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "Path", TRUE)) + { + AnscCopyString(pWanDmlIface->IP.Path, pString); + ret = TRUE; + } + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + + return ret; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL WanIfIpCfg_Validate(ANSC_HANDLE hInsContext, char* pReturnParamName, ULONG* puLength); + + description: + + This function is called to set ULONG parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + ULONG uValue + The updated ULONG value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL WanIfIpCfg_Validate(ANSC_HANDLE hInsContext, char* pReturnParamName, ULONG* puLength) +{ + return TRUE; +} + +/********************************************************************** + caller: owner of this object + + prototype: + ULONG WanIfIpCfg_Commit(ANSC_HANDLE hInsContext); + + description: + This function is called to finally commit all the update. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: The status of the operation. +**********************************************************************/ +ULONG WanIfIpCfg_Commit(ANSC_HANDLE hInsContext) +{ + return 0; +} + +/********************************************************************** + caller: owner of this object + + prototype: + ULONG WanIfIpCfg_Rollback(ANSC_HANDLE hInsContext); + + description: + This function is called to roll back the update whenever there's a + validation found. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: The status of the operation. +**********************************************************************/ +ULONG WanIfIpCfg_Rollback(ANSC_HANDLE hInsContext) +{ + return 0; +} + +/*********************************************************************** + + APIs for Object: + + X_RDK_WanManager.CPEInterface.{i}.MAPT. + + * WanIfMapt_GetParamUlongValue + * WanIfMapt_SetParamUlongValue + * WanIfMapt_GetParamStringValue + * WanIfMapt_SetParamStringValue + * WanIfMapt_Validate + * WanIfMapt_Commit + * WanIfMapt_Rollback + +***********************************************************************/ + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL WanIfMapt_GetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG* puLong); + + description: + + This function is called to retrieve ULONG parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + ULONG* puLong + The buffer of returned ULONG value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL WanIfMapt_GetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG* puLong) +{ + BOOL ret = FALSE; + + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "MAPTStatus", TRUE)) + { + *puLong = pWanDmlIface->MAP.MaptStatus; + ret = TRUE; + } + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + + return ret; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL WanIfMapt_SetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG uValue); + + description: + + This function is called to set ULONG parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + ULONG uValue + The updated ULONG value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL WanIfMapt_SetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG uValue) +{ + BOOL ret = FALSE; + + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "MAPTStatus", TRUE)) + { +#ifdef FEATURE_MAPT + pWanDmlIface->MAP.MaptStatus = uValue; + ret = TRUE; +#endif /* * FEATURE_MAPT */ + } + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + + return ret; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG WanIfMapt_GetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pValue, ULONG* pUlSize); + + description: + + This function is called to retrieve string parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + char* pValue, + The string value buffer; + + ULONG* pUlSize + The buffer of length of string value; + Usually size of 1023 will be used. + If it's not big enough, put required size here and return 1; + + return: 0 if succeeded; + 1 if short of buffer size; (*pUlSize = required size) + -1 if not supported. + +**********************************************************************/ +ULONG WanIfMapt_GetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pValue, ULONG* pUlSize) +{ + ULONG ret = -1; + + + + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "Path", TRUE) ) + { + /* collect value */ + if ( ( sizeof( pWanDmlIface->MAP.Path ) - 1 ) < *pUlSize ) + { + AnscCopyString( pValue, pWanDmlIface->MAP.Path ); + ret = 0; + } + else + { + *pUlSize = sizeof( pWanDmlIface->MAP.Path ); + ret = 1; + } + } + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + + return ret; + +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL WanIfMapt_SetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pString); + + description: + + This function is called to set string parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + char* pString + The updated string value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL WanIfMapt_SetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pString) +{ + BOOL ret = FALSE; + + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "Path", TRUE)) + { +#ifdef FEATURE_MAPT + AnscCopyString(pWanDmlIface->MAP.Path, pString); + ret = TRUE; +#endif /* * FEATURE_MAPT */ + } + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + + return ret; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL WanIfMapt_Validate(ANSC_HANDLE hInsContext, char* pReturnParamName, ULONG* puLength); + + description: + + This function is called to set ULONG parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + ULONG uValue + The updated ULONG value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL WanIfMapt_Validate(ANSC_HANDLE hInsContext, char* pReturnParamName, ULONG* puLength) +{ + return TRUE; +} + +/********************************************************************** + caller: owner of this object + + prototype: + ULONG WanIfMapt_Commit(ANSC_HANDLE hInsContext); + + description: + This function is called to finally commit all the update. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: The status of the operation. +**********************************************************************/ +ULONG WanIfMapt_Commit(ANSC_HANDLE hInsContext) +{ + return 0; +} + +/********************************************************************** + caller: owner of this object + + prototype: + ULONG WanIfMapt_Rollback(ANSC_HANDLE hInsContext); + + description: + This function is called to roll back the update whenever there's a + validation found. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: The status of the operation. +**********************************************************************/ +ULONG WanIfMapt_Rollback(ANSC_HANDLE hInsContext) +{ + return 0; +} + +/*********************************************************************** + + APIs for Object: + + X_RDK_WanManager.CPEInterface.{i}.MAPT. + + * WanIfDSLite_GetParamUlongValue + * WanIfDSLite_SetParamUlongValue + * WanIfDSLite_GetParamStringValue + * WanIfDSLite_SetParamStringValue + * WanIfDSLite_Validate + * WanIfDSLite_Commit + * WanIfDSLite_Rollback + +***********************************************************************/ + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL WanIfDSLite_GetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG* puLong); + + description: + + This function is called to retrieve ULONG parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + ULONG* puLong + The buffer of returned ULONG value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL WanIfDSLite_GetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG* puLong) +{ + BOOL ret = FALSE; + + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "Status", TRUE)) + { + *puLong = pWanDmlIface->DSLite.Status; + ret = TRUE; + } + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + + return ret; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL WanIfDSLite_SetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG uValue); + + description: + + This function is called to set ULONG parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + ULONG uValue + The updated ULONG value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL WanIfDSLite_SetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG uValue) +{ + BOOL ret = FALSE; + + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "Status", TRUE)) + { + pWanDmlIface->DSLite.Status = uValue; + ret = TRUE; + } + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + + return ret; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG WanIfDSLite_GetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pValue, ULONG* pUlSize); + + description: + + This function is called to retrieve string parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + char* pValue, + The string value buffer; + + ULONG* pUlSize + The buffer of length of string value; + Usually size of 1023 will be used. + If it's not big enough, put required size here and return 1; + + return: 0 if succeeded; + 1 if short of buffer size; (*pUlSize = required size) + -1 if not supported. + +**********************************************************************/ +ULONG WanIfDSLite_GetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pValue, ULONG* pUlSize) +{ + ULONG ret = -1; + + + + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "Path", TRUE) ) + { + /* collect value */ + if ( ( sizeof( pWanDmlIface->DSLite.Path ) - 1 ) < *pUlSize ) + { + AnscCopyString( pValue, pWanDmlIface->DSLite.Path ); + ret = 0; + } + else + { + *pUlSize = sizeof( pWanDmlIface->DSLite.Path ); + ret = 1; + } + } + + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + + return ret; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL WanIfDSLite_SetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pString); + + description: + + This function is called to set string parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + char* pString + The updated string value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL WanIfDSLite_SetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pString) +{ + BOOL ret = FALSE; + + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "Path", TRUE)) + { + AnscCopyString(pWanDmlIface->DSLite.Path, pString); + ret = TRUE; + } + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + + return ret; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL WanIfDSLite_Validate(ANSC_HANDLE hInsContext, char* pReturnParamName, ULONG* puLength); + + description: + + This function is called to set ULONG parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + ULONG uValue + The updated ULONG value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL WanIfDSLite_Validate(ANSC_HANDLE hInsContext, char* pReturnParamName, ULONG* puLength) +{ + return TRUE; +} + +/********************************************************************** + caller: owner of this object + + prototype: + ULONG WanIfDSLite_Commit(ANSC_HANDLE hInsContext); + + description: + This function is called to finally commit all the update. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: The status of the operation. +**********************************************************************/ +ULONG WanIfDSLite_Commit(ANSC_HANDLE hInsContext) +{ + return 0; +} + +/********************************************************************** + caller: owner of this object + + prototype: + ULONG WanIfDSLite_Rollback(ANSC_HANDLE hInsContext); + + description: + This function is called to roll back the update whenever there's a + validation found. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: The status of the operation. +**********************************************************************/ +ULONG WanIfDSLite_Rollback(ANSC_HANDLE hInsContext) +{ + return 0; +} + +/*********************************************************************** + + APIs for Object: + + Device.X_RDK_WanManager.CPEInterface.{I}.Marking.{i}. + + * Marking_GetEntryCount + * Marking_GetEntry + * Marking_AddEntry + * Marking_DelEntry + * Marking_GetParamUlongValue + * Marking_GetParamStringValue + * Marking_GetParamIntValue + * Marking_SetParamUlongValue + * Marking_SetParamStringValue + * Marking_SetParamIntValue + * Marking_Validate + * Marking_Commit + * Marking_Rollback + +***********************************************************************/ +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG Marking_GetEntryCount(ANSC_HANDLE hInsContext); + + description: + + This function is called to retrieve the count of the table. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: The count of the table + +**********************************************************************/ + +ULONG Marking_GetEntryCount(ANSC_HANDLE hInsContext) +{ + + ULONG count = 0; + + + +#ifdef FEATURE_802_1P_COS_MARKING + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + + /* check the parameter name and set the corresponding value */ + count = AnscSListQueryDepth( &(pWanDmlIface->Marking.MarkingList) ); + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } +#endif /* * FEATURE_802_1P_COS_MARKING */ + + return count; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ANSC_HANDLE Marking_GetEntry(ANSC_HANDLE hInsContext, ULONG nIndex, ULONG* pInsNumber); + + description: + + This function is called to retrieve the entry specified by the index. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + ULONG nIndex, + The index of this entry; + + ULONG* pInsNumber + The output instance number; + + return: The handle to identify the entry + +**********************************************************************/ + +ANSC_HANDLE Marking_GetEntry(ANSC_HANDLE hInsContext, ULONG nIndex, ULONG* pInsNumber) +{ + PSINGLE_LINK_ENTRY pSListEntry = NULL; + *pInsNumber= 0; + +#ifdef FEATURE_802_1P_COS_MARKING + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + + /* check the parameter name and set the corresponding value */ + pSListEntry = AnscSListGetEntryByIndex(&(pWanDmlIface->Marking.MarkingList), nIndex); + if ( pSListEntry ) + { + CONTEXT_MARKING_LINK_OBJECT* pCxtLink = ACCESS_CONTEXT_MARKING_LINK_OBJECT(pSListEntry); + *pInsNumber = pCxtLink->InstanceNumber; + } + + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } +#endif /* * FEATURE_802_1P_COS_MARKING */ + + return (ANSC_HANDLE)pSListEntry; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ANSC_HANDLE Marking_AddEntry(ANSC_HANDLE hInsContext, ULONG* pInsNumber); + + description: + + This function is called to add a new entry. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + ULONG* pInsNumber + The output instance number; + + return: The handle of new added entry. + +**********************************************************************/ + +ANSC_HANDLE Marking_AddEntry(ANSC_HANDLE hInsContext, ULONG* pInsNumber) +{ + ANSC_HANDLE newMarking = NULL; + +#ifdef FEATURE_802_1P_COS_MARKING + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + + /* check the parameter name and set the corresponding value */ + newMarking = WanManager_AddIfaceMarking(pWanDmlIface, pInsNumber); + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } +#endif /* * FEATURE_802_1P_COS_MARKING */ + + return newMarking; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG Marking_DelEntry(ANSC_HANDLE hInsContext, ANSC_HANDLE hInstance); + + description: + + This function is called to delete an exist entry. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + ANSC_HANDLE hInstance + The exist entry handle; + + return: The status of the operation. + +**********************************************************************/ + +ULONG Marking_DelEntry(ANSC_HANDLE hInsContext, ANSC_HANDLE hInstance) +{ + + ULONG returnStatus = -1; + +#ifdef FEATURE_802_1P_COS_MARKING + CONTEXT_MARKING_LINK_OBJECT* pMarkingCxtLink = (CONTEXT_MARKING_LINK_OBJECT*)hInstance; + if(pMarkingCxtLink == NULL) + { + return -1; + } + + + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + + + if ( pMarkingCxtLink->bNew ) + { + /* Set bNew to FALSE to indicate this node is not going to save to SysRegistry */ + pMarkingCxtLink->bNew = FALSE; + } + + DML_MARKING* p_Marking = (DML_MARKING*)pMarkingCxtLink->hContext; + + returnStatus = DmlDeleteMarking( NULL, p_Marking ); + + if ( ( ANSC_STATUS_SUCCESS == returnStatus ) && \ + ( AnscSListPopEntryByLink(&(pWanDmlIface->Marking.MarkingList), &pMarkingCxtLink->Linkage) ) ) + { + AnscFreeMemory(pMarkingCxtLink->hContext); + AnscFreeMemory(pMarkingCxtLink); + } + + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } +#endif /* * FEATURE_802_1P_COS_MARKING */ + + return returnStatus; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL Marking_GetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG* puLong); + + description: + + This function is called to retrieve ULONG parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + ULONG* puLong + The buffer of returned ULONG value; + + return: TRUE if succeeded. + +**********************************************************************/ + +BOOL Marking_GetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG* puLong) +{ + BOOL ret = FALSE; + CONTEXT_MARKING_LINK_OBJECT* pCxtLink = (CONTEXT_MARKING_LINK_OBJECT*)hInsContext; + DML_MARKING* p_Marking = (DML_MARKING* )pCxtLink->hContext; + + /* check the parameter name and return the corresponding value */ + if( AnscEqualString(ParamName, "SKBPort", TRUE)) + { + *puLong = p_Marking->SKBPort; + ret = TRUE; + } + if( AnscEqualString(ParamName, "SKBMark", TRUE)) + { + *puLong = p_Marking->SKBMark; + ret = TRUE; + } + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return ret; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG Marking_GetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pValue, ULONG* pUlSize); + + description: + + This function is called to retrieve string parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + char* pValue, + The string value buffer; + + ULONG* pUlSize + The buffer of length of string value; + Usually size of 1023 will be used. + If it's not big enough, put required size here and return 1; + + return: 0 if succeeded; + 1 if short of buffer size; (*pUlSize = required size) + -1 if not supported. + +**********************************************************************/ + +ULONG Marking_GetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pValue, ULONG* pUlSize) +{ + CONTEXT_MARKING_LINK_OBJECT* pCxtLink = (CONTEXT_MARKING_LINK_OBJECT*)hInsContext; + DML_MARKING* p_Marking = (DML_MARKING* )pCxtLink->hContext; + + /* check the parameter name and return the corresponding value */ + if( AnscEqualString(ParamName, "Alias", TRUE)) + { + if ( AnscSizeOfString(p_Marking->Alias) < *pUlSize) + { + AnscCopyString(pValue, p_Marking->Alias); + return 0; + } + else + { + *pUlSize = AnscSizeOfString(p_Marking->Alias)+1; + return 1; + } + } + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return -1; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL Marking_GetParamIntValue(ANSC_HANDLE hInsContext, char* ParamName, int* pInt); + + description: + + This function is called to retrieve integer parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + int* pInt + The buffer of returned integer value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL Marking_GetParamIntValue(ANSC_HANDLE hInsContext, char* ParamName, int* pInt) +{ + BOOL ret = FALSE; + CONTEXT_MARKING_LINK_OBJECT* pCxtLink = (CONTEXT_MARKING_LINK_OBJECT*)hInsContext; + DML_MARKING* p_Marking = (DML_MARKING* )pCxtLink->hContext; + + /* check the parameter name and return the corresponding value */ + if( AnscEqualString(ParamName, "EthernetPriorityMark", TRUE)) + { + *pInt = p_Marking->EthernetPriorityMark; + ret = TRUE; + } + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return ret; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL Marking_SetParamIntValue(ANSC_HANDLE hInsContext, char* ParamName, int iValue); + + description: + + This function is called to set integer parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + int iValue + The updated integer value; + + return: TRUE if succeeded. + +**********************************************************************/ +BOOL Marking_SetParamIntValue(ANSC_HANDLE hInsContext, char* ParamName, int iValue) +{ + BOOL ret = FALSE; + CONTEXT_MARKING_LINK_OBJECT* pCxtLink = (CONTEXT_MARKING_LINK_OBJECT*)hInsContext; + DML_MARKING* p_Marking = (DML_MARKING* )pCxtLink->hContext; + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "EthernetPriorityMark", TRUE)) + { + p_Marking->EthernetPriorityMark = iValue; + ret = TRUE; + } + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return ret; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL Marking_SetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG uValue); + + description: + + This function is called to set ULONG parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + ULONG uValue + The updated ULONG value; + + return: TRUE if succeeded. + +**********************************************************************/ + +BOOL Marking_SetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG uValue) +{ + return FALSE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL Marking_SetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pString); + + description: + + This function is called to set string parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + char* pString + The updated string value; + + return: TRUE if succeeded. + +**********************************************************************/ + +BOOL Marking_SetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pString) +{ + BOOL ret = FALSE; + CONTEXT_MARKING_LINK_OBJECT* pCxtLink = (CONTEXT_MARKING_LINK_OBJECT*)hInsContext; + DML_MARKING* p_Marking = (DML_MARKING* )pCxtLink->hContext; + + /* check the parameter name and set the corresponding value */ + + if( AnscEqualString(ParamName, "Alias", TRUE)) + { + //Alias should not overwrite after set + if( 0 < AnscSizeOfString(p_Marking->Alias) ) + { + return FALSE; + } + + AnscCopyString(p_Marking->Alias, pString); + ret = TRUE; + } + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return ret; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL Marking_Validate(ANSC_HANDLE hInsContext, char* pReturnParamName, ULONG* puLength); + + description: + + This function is called to finally commit all the update. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* pReturnParamName, + The buffer (128 bytes) of parameter name if there's a validation. + + ULONG* puLength + The output length of the param name. + + return: TRUE if there's no validation. + +**********************************************************************/ + +BOOL Marking_Validate(ANSC_HANDLE hInsContext, char* pReturnParamName, ULONG* puLength) +{ + return TRUE; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG Marking_Commit(ANSC_HANDLE hInsContext); + + description: + + This function is called to finally commit all the update. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: The status of the operation. + +**********************************************************************/ + +ULONG Marking_Commit(ANSC_HANDLE hInsContext) +{ + + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + CONTEXT_MARKING_LINK_OBJECT* pCxtLink = (CONTEXT_MARKING_LINK_OBJECT*)hInsContext; + DML_MARKING* p_Marking = (DML_MARKING* )pCxtLink->hContext; + + if ( pCxtLink->bNew ) + { + //Add new marking params + returnStatus = DmlAddMarking( NULL, p_Marking ); + + if ( returnStatus == ANSC_STATUS_SUCCESS ) + { + pCxtLink->bNew = FALSE; + } + else + { + //Re-init all memory + memset( p_Marking->Alias, 0, sizeof( p_Marking->Alias ) ); + p_Marking->SKBPort = 0; + p_Marking->SKBMark = 0; + p_Marking->EthernetPriorityMark = -1; + } + } + else + { + //Update marking param values + returnStatus = DmlSetMarking( NULL, p_Marking ); + } + + return returnStatus; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG Marking_Rollback(ANSC_HANDLE hInsContext); + + description: + + This function is called to roll back the update whenever there's a + validation found. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: The status of the operation. + +**********************************************************************/ + +ULONG Marking_Rollback(ANSC_HANDLE hInsContext) +{ + return 0; +} + +/*********************************************************************** + + APIs for Object: + + X_RDK_WanManager.CPEInterface.{i}.PPP. + + * WanIfPPPCfg_GetParamUlongValue + * WanIfPPPCfg_SetParamUlongValue + * WanIfPPPCfg_GetParamStringValue + * WanIfPPPCfg_SetParamStringValue + * WanIfPPPCfg_GetParamBoolValue + * WanIfPPPCfg_SetParamBoolValue + * WanIfPPPCfg_Validate + * WanIfPPPCfg_Commit + * WanPPPIpCfg_Rollback + +***********************************************************************/ + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + WanIfPPPCfg_GetParamUlongValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + ULONG* puLong + ); + + description: + + This function is called to retrieve ULONG parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + ULONG* puLong + The buffer of returned ULONG value; + + return: TRUE if succeeded. + +**********************************************************************/ + +BOOL +WanIfPPPCfg_GetParamUlongValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + ULONG* puLong + ) +{ + BOOL ret = FALSE; + + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + + /* check the parameter name and return the corresponding value */ + if( AnscEqualString(ParamName, "IPCPStatus", TRUE)) + { + *puLong = pWanDmlIface->PPP.IPCPStatus; + ret = TRUE; + } + if( AnscEqualString(ParamName, "IPv6CPStatus", TRUE)) + { + *puLong = pWanDmlIface->PPP.IPV6CPStatus; + ret = TRUE; + } + if( AnscEqualString(ParamName, "LCPStatus", TRUE)) + { + *puLong = pWanDmlIface->PPP.LCPStatus; + ret = TRUE; + } + if( AnscEqualString(ParamName, "LinkStatus", TRUE)) + { + *puLong = pWanDmlIface->PPP.LinkStatus; + ret = TRUE; + } + if( AnscEqualString(ParamName, "LinkType", TRUE)) + { + *puLong = pWanDmlIface->PPP.LinkType; + ret = TRUE; + } + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return ret; + +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + WanIfPPPCfg_SetParamUlongValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + ULONG uValue + ); + + description: + + This function is called to set ULONG parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + ULONG uValue + The updated ULONG value; + + return: TRUE if succeeded. + +**********************************************************************/ + +BOOL +WanIfPPPCfg_SetParamUlongValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + ULONG uValue + ) +{ + BOOL ret = FALSE; + int iErrorCode = 0; + char *pInterface = NULL; + pthread_t IPCPHandlerThread; + pthread_t IPV6CPHandlerThread; + + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "IPCPStatus", TRUE)) + { + pWanDmlIface->PPP.IPCPStatus = uValue; + pInterface = (char *) malloc(64); + if (pInterface != NULL) + { + strncpy(pInterface, pWanDmlIface->Wan.Name, 64); + iErrorCode = pthread_create( &IPCPHandlerThread, NULL, &IPCPStateChangeHandler, (void*) pInterface ); + if( 0 != iErrorCode ) + { + CcspTraceInfo(("%s %d - Failed to handle IPCP event change %d\n", __FUNCTION__, __LINE__, iErrorCode )); + } + ret = TRUE; + } + } + if( AnscEqualString(ParamName, "IPv6CPStatus", TRUE)) + { + pWanDmlIface->PPP.IPV6CPStatus = uValue; + pInterface = (char *) malloc(64); + if (pInterface != NULL) + { + strncpy(pInterface, pWanDmlIface->Wan.Name, 64); + iErrorCode = pthread_create( &IPCPHandlerThread, NULL, &IPV6CPStateChangeHandler, (void*) pInterface ); + if( 0 != iErrorCode ) + { + CcspTraceInfo(("%s %d - Failed to handle IPV6CP event change %d\n", __FUNCTION__, __LINE__, iErrorCode )); + } + ret = TRUE; + } + } + if( AnscEqualString(ParamName, "LCPStatus", TRUE)) + { + pWanDmlIface->PPP.LCPStatus = uValue; + ret = TRUE; + } + if( AnscEqualString(ParamName, "LinkStatus", TRUE)) + { + pWanDmlIface->PPP.LinkStatus = uValue; + ret = TRUE; + } + if( AnscEqualString(ParamName, "LinkType", TRUE)) + { + pWanDmlIface->PPP.LinkType = uValue; + ret = TRUE; + } + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return ret; +} + + +/********************************************************************** + + caller: owner of this object + + prototype: + + ULONG + WanIfPPPCfg_GetParamStringValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + char* pValue, + ULONG* pUlSize + ); + + description: + + This function is called to retrieve string parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + char* pValue, + The string value buffer; + + ULONG* pUlSize + The buffer of length of string value; + Usually size of 1023 will be used. + If it's not big enough, put required size here and return 1; + + return: 0 if succeeded; + 1 if short of buffer size; (*pUlSize = required size) + -1 if not supported. + +**********************************************************************/ + +ULONG +WanIfPPPCfg_GetParamStringValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + char* pValue, + ULONG* pUlSize + ) +{ + ULONG ret = -1; + + + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "Path", TRUE) ) + { + /* collect value */ + if ( ( sizeof( pWanDmlIface->Phy.Path ) - 1 ) < *pUlSize ) + { + AnscCopyString( pValue, pWanDmlIface->PPP.Path); + ret = 0; + } + else + { + *pUlSize = sizeof( pWanDmlIface->PPP.Path ); + ret = 1; + } + } + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + + return ret; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + WanIfPPPCfg_SetParamStringValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + char* pString + ); + + description: + + This function is called to set string parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + char* pString + The updated string value; + + return: TRUE if succeeded. + +**********************************************************************/ + +BOOL +WanIfPPPCfg_SetParamStringValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + char* pString + ) +{ + BOOL ret = FALSE; + + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "Path", TRUE)) + { + AnscCopyString(pWanDmlIface->PPP.Path, pString); + ret = TRUE; + } + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + + return ret; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + WanIfPPPCfg_GetParamBoolValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + BOOL* pBool + ); + + description: + + This function is called to retrieve Boolean parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + BOOL* pBool + The buffer of returned boolean value; + + return: TRUE if succeeded. + +**********************************************************************/ + +ULONG +WanIfPPPCfg_GetParamBoolValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + BOOL* pBool + ) +{ + BOOL ret = FALSE; + + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + /* check the parameter name and return the corresponding value */ + if( AnscEqualString(ParamName, "Enable", TRUE)) + { + *pBool = pWanDmlIface->PPP.Enable; + ret = TRUE; + } + if( AnscEqualString(ParamName, "IPCPEnable", TRUE)) + { + *pBool = pWanDmlIface->PPP.IPCPEnable; + ret = TRUE; + } + if( AnscEqualString(ParamName, "IPv6CPEnable", TRUE)) + { + *pBool = pWanDmlIface->PPP.IPV6CPEnable; + ret = TRUE; + } + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + + return ret; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + WanIfPPPCfg_SetParamBoolValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + BOOL bValue + ); + + description: + + This function is called to set string parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + char* pString + The updated string value; + + return: TRUE if succeeded. + +**********************************************************************/ + +BOOL +WanIfPPPCfg_SetParamBoolValue + ( + ANSC_HANDLE hInsContext, + char* ParamName, + BOOL bValue + ) +{ + BOOL ret = FALSE; + + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + + /* check the parameter name and set the corresponding value */ + if( AnscEqualString(ParamName, "Enable", TRUE)) + { + pWanDmlIface->PPP.Enable = bValue; + ret = TRUE; + } + if( AnscEqualString(ParamName, "IPCPEnable", TRUE)) + { + pWanDmlIface->PPP.IPCPEnable = bValue; + ret = TRUE; + } + if( AnscEqualString(ParamName, "IPv6CPEnable", TRUE)) + { + pWanDmlIface->PPP.IPV6CPEnable = bValue; + ret = TRUE; + } + } + } + + /* CcspTraceWarning(("Unsupported parameter '%s'\n", ParamName)); */ + return ret; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + WanIfPPPCfg_Validate + ( + ANSC_HANDLE hInsContext, + char* pReturnParamName, + ULONG* puLength + ) + description: + + This function is called to set ULONG parameter value; + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + char* ParamName, + The parameter name; + + ULONG uValue + The updated ULONG value; + + return: TRUE if succeeded. + +**********************************************************************/ + +BOOL +WanIfPPPCfg_Validate + ( + ANSC_HANDLE hInsContext, + char* ParamName, + BOOL bValue + ) +{ + return TRUE; +} + +/********************************************************************** + caller: owner of this object + + prototype: + ULONG + WanIfPPPCfg_Commit + ( + ANSC_HANDLE hInsContext + ); + + description: + This function is called to finally commit all the update. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: The status of the operation. +**********************************************************************/ + +ULONG +WanIfPPPCfg_Commit + ( + ANSC_HANDLE hInsContext + ) +{ + ULONG ret = -1; + + ANSC_STATUS result; + + WanMgr_Iface_Data_t* pIfaceDmlEntry = (WanMgr_Iface_Data_t*) hInsContext; + if(pIfaceDmlEntry != NULL) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pIfaceDmlEntry->data.uiIfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pWanDmlIfaceData->data); + + result = DmlSetWanIfCfg( pWanDmlIface->uiInstanceNumber, pWanDmlIface ); + if(result != ANSC_STATUS_SUCCESS) + { + AnscTraceError(("%s: Failed \n", __FUNCTION__)); + } + else + { + ret = 0; + } + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + + return ret; +} + +/********************************************************************** + caller: owner of this object + + prototype: + ULONG + WanIfPPPCfg_Rollback + ( + ANSC_HANDLE hInsContext + ); + + description: + This function is called to roll back the update whenever there's a + validation found. + + argument: ANSC_HANDLE hInsContext, + The instance handle; + + return: The status of the operation. +**********************************************************************/ + +ULONG +WanIfPPPCfg_Rollback + ( + ANSC_HANDLE hInsContext + ) +{ + return TRUE; +} diff --git a/source/TR-181/middle_layer_src/wanmgr_dml_iface_apis.h b/source/TR-181/middle_layer_src/wanmgr_dml_iface_apis.h new file mode 100644 index 00000000..3238cd92 --- /dev/null +++ b/source/TR-181/middle_layer_src/wanmgr_dml_iface_apis.h @@ -0,0 +1,303 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2019 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +/********************************************************************** + Copyright [2014] [Cisco Systems, Inc.] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +**********************************************************************/ +#ifndef _WANMGR_DML_IFACE_APIS_H_ +#define _WANMGR_DML_IFACE_APIS_H_ + +#include "ansc_platform.h" + +/*********************************************************************** + + APIs for Object: + + X_RDK_WanManager.CPEInterface. + + * WanIf_GetEntryCount + * WanIf_GetEntry + * WanIf_AddEntry + * WanIf_DelEntry + * WanIf_GetParamStringValue + * WanIf_SetParamStringValue + * WanIf_Validate + * WanIf_Commit + * WanIf_Rollback + +***********************************************************************/ +ULONG WanIf_GetEntryCount(ANSC_HANDLE); +ANSC_HANDLE WanIf_GetEntry(ANSC_HANDLE hInsContext, ULONG nIndex, ULONG* pInsNumber); +ANSC_HANDLE WanIf_AddEntry(ANSC_HANDLE hInsContext, ULONG* pInsNumber); +ULONG WanIf_DelEntry(ANSC_HANDLE hInsContext, ANSC_HANDLE hInstance); +ULONG WanIf_GetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pValue, ULONG* pUlSize); +BOOL WanIf_SetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pString); +BOOL WanIf_Validate(ANSC_HANDLE hInsContext, char* pReturnParamName, ULONG* puLength); +ULONG WanIf_Commit(ANSC_HANDLE hInsContext); +ULONG WanIf_Rollback(ANSC_HANDLE hInsContext); + +/*********************************************************************** + + APIs for Object: + + X_RDK_WanManager.CPEInterface.{i}.Phy. + + * WanIfPhy_GetParamStringValue + * WanIfPhy_SetParamStringValue + * WanIfPhy_GetParamUlongValue + * WanIfPhy_SetParamUlongValue + * WanIfPhy_Validate + * WanIfPhy_Commit + * WanIfPhy_Rollback + +***********************************************************************/ + + +ULONG WanIfPhy_GetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pValue, ULONG* pUlSize); +BOOL WanIfPhy_SetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pString); +BOOL WanIfPhy_GetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG* puLong); +BOOL WanIfPhy_SetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG uValue); +BOOL WanIfPhy_Validate(ANSC_HANDLE hInsContext, char* pReturnParamName, ULONG* puLength); +ULONG WanIfPhy_Commit(ANSC_HANDLE hInsContext); +ULONG WanIfPhy_Rollback(ANSC_HANDLE hInsContext); + +/*********************************************************************** + + APIs for Object: + + X_RDK_WanManager.CPEInterface.{i}.Wan. + + * WanIfCfg_GetParamUlongValue + * WanIfCfg_SetParamUlongValue + * WanIfCfg_GetParamIntValue + * WanIfCfg_SetParamIntValue + * WanIfCfg_GetParamBoolValue + * WanIfCfg_SetParamBoolValue + * WanIfCfg_GetParamStringValue + * WanIfCfg_SetParamStringValue + * WanIfCfg_Validate + * WanIfCfg_Commit + * WanIfCfg_Rollback + +***********************************************************************/ + +BOOL WanIfCfg_GetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG* puLong); +BOOL WanIfCfg_SetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG uValue); +BOOL WanIfCfg_GetParamIntValue(ANSC_HANDLE hInsContext, char* ParamName, int* pInt); +BOOL WanIfCfg_SetParamIntValue(ANSC_HANDLE hInsContext, char* ParamName, int iValue); +BOOL WanIfCfg_GetParamBoolValue(ANSC_HANDLE hInsContext, char* ParamName, BOOL* pBool); +BOOL WanIfCfg_SetParamBoolValue(ANSC_HANDLE hInsContext, char* ParamName, BOOL bValue); +ULONG WanIfCfg_GetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pValue, ULONG* pUlSize); +BOOL WanIfCfg_SetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pString); +BOOL WanIfCfg_Validate(ANSC_HANDLE hInsContext, char* pReturnParamName, ULONG* puLength); +ULONG WanIfCfg_Commit(ANSC_HANDLE hInsContext); +ULONG WanIfCfg_Rollback(ANSC_HANDLE hInsContext); + +/*********************************************************************** + + APIs for Object: + + X_RDK_WanManager.CPEInterface.{i}.Wan.Validation. + + * WanIfValidation_GetParamBoolValue + * WanIfValidation_SetParamBoolValue + * WanIfValidation_Validate + * WanIfValidation_Commit + * WanIfValidation_Rollback + +***********************************************************************/ +BOOL WanIfValidation_GetParamBoolValue(ANSC_HANDLE hInsContext, char* ParamName, BOOL* bValue); +BOOL WanIfValidation_SetParamBoolValue(ANSC_HANDLE hInsContext, char *ParamName, BOOL bValue); +BOOL WanIfValidation_Validate(ANSC_HANDLE hInsContext, char* pReturnParamName, ULONG* puLength); +ULONG WanIfValidation_Commit(ANSC_HANDLE hInsContext); +ULONG WanIfValidation_Rollback(ANSC_HANDLE hInsContext); + +/*********************************************************************** + + APIs for Object: + + X_RDK_WanManager.CPEInterface.{i}.DynamicTrigger. + + * WanIfDynTrigger_GetParamUlongValue + * WanIfDynTrigger_GetParamBoolValue + * WanIfDynTrigger_SetParamUlongValue + * WanIfDynTrigger_SetParamBoolValue + * WanIfDynTrigger_Validate + * WanIfDynTrigger_Commit + * WanIfDynTrigger_Rollback + +***********************************************************************/ + +BOOL WanIfDynTrigger_GetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG* puLong); +BOOL WanIfDynTrigger_SetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG uValue); +BOOL WanIfDynTrigger_GetParamBoolValue(ANSC_HANDLE hInsContext, char* ParamName, BOOL* pBool); +BOOL WanIfDynTrigger_SetParamBoolValue(ANSC_HANDLE hInsContext, char* ParamName, BOOL bValue); +BOOL WanIfDynTrigger_Validate(ANSC_HANDLE hInsContext, char* pReturnParamName, ULONG* puLength); +ULONG WanIfDynTrigger_Commit(ANSC_HANDLE hInsContext); +ULONG WanIfDynTrigger_Rollback(ANSC_HANDLE hInsContext); + +/*********************************************************************** + + APIs for Object: + + X_RDK_WanManager.CPEInterface.{i}.IP. + + * WanIfIpCfg_GetParamUlongValue + * WanIfIpCfg_SetParamUlongValue + * WanIfIpCfg_GetParamStringValue + * WanIfIpCfg_SetParamStringValue + * WanIfIpCfg_Validate + * WanIfIpCfg_Commit + * WanIfIpCfg_Rollback + +***********************************************************************/ + +BOOL WanIfIpCfg_GetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG* puLong); +BOOL WanIfIpCfg_SetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG uValue); +ULONG WanIfIpCfg_GetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pValue, ULONG* pUlSize); +BOOL WanIfIpCfg_SetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pString); +BOOL WanIfIpCfg_Validate(ANSC_HANDLE hInsContext, char* pReturnParamName, ULONG* puLength); +ULONG WanIfIpCfg_Commit(ANSC_HANDLE hInsContext); +ULONG WanIfIpCfg_Rollback(ANSC_HANDLE hInsContext); + +/*********************************************************************** + + APIs for Object: + + X_RDK_WanManager.CPEInterface.{i}.MAPT. + + * WanIfMapt_GetParamUlongValue + * WanIfMapt_SetParamUlongValue + * WanIfMapt_GetParamStringValue + * WanIfMapt_SetParamStringValue + * WanIfMapt_Validate + * WanIfMapt_Commit + * WanIfMapt_Rollback + +***********************************************************************/ + +BOOL WanIfMapt_GetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG* puLong); +BOOL WanIfMapt_SetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG uValue); +ULONG WanIfMapt_GetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pValue, ULONG* pUlSize); +BOOL WanIfMapt_SetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pString); +BOOL WanIfMapt_Validate(ANSC_HANDLE hInsContext, char* pReturnParamName, ULONG* puLength); +ULONG WanIfMapt_Commit(ANSC_HANDLE hInsContext); +ULONG WanIfMapt_Rollback(ANSC_HANDLE hInsContext); + +/*********************************************************************** + + APIs for Object: + + X_RDK_WanManager.CPEInterface.{i}.DSLite. + + * WanIfDSLite_GetParamUlongValue + * WanIfDSLite_SetParamUlongValue + * WanIfDSLite_GetParamStringValue + * WanIfDSLite_SetParamStringValue + * WanIfDSLite_Validate + * WanIfDSLite_Commit + * WanIfDSLite_Rollback + +***********************************************************************/ + +BOOL WanIfDSLite_GetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG* puLong); +BOOL WanIfDSLite_SetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG uValue); +ULONG WanIfDSLite_GetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pValue, ULONG* pUlSize); +BOOL WanIfDSLite_SetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pString); +BOOL WanIfDSLite_Validate(ANSC_HANDLE hInsContext, char* pReturnParamName, ULONG* puLength); +ULONG WanIfDSLite_Commit(ANSC_HANDLE hInsContext); +ULONG WanIfDSLite_Rollback(ANSC_HANDLE hInsContext); + +/*********************************************************************** + + APIs for Object: + + Device.X_RDK_WanManager.CPEInterface.{i}.Marking.{i}. + + * Marking_GetEntryCount + * Marking_GetEntry + * Marking_AddEntry + * Marking_DelEntry + * Marking_GetParamUlongValue + * Marking_GetParamStringValue + * Marking_GetParamIntValue + * Marking_SetParamIntValue + * Marking_SetParamUlongValue + * Marking_SetParamStringValue + * Marking_Validate + * Marking_Commit + * Marking_Rollback + +***********************************************************************/ + +ULONG Marking_GetEntryCount(ANSC_HANDLE hInsContext); +ANSC_HANDLE Marking_GetEntry(ANSC_HANDLE hInsContext, ULONG nIndex, ULONG* pInsNumber); +ANSC_HANDLE Marking_AddEntry(ANSC_HANDLE hInsContext, ULONG* pInsNumber); +ULONG Marking_DelEntry(ANSC_HANDLE hInsContext, ANSC_HANDLE hInstance); +BOOL Marking_GetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG* puLong); +ULONG Marking_GetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pValue, ULONG* pUlSize); +BOOL Marking_GetParamIntValue(ANSC_HANDLE hInsContext, char* ParamName, int* pInt); +BOOL Marking_SetParamIntValue(ANSC_HANDLE hInsContext, char* ParamName, int iValue); +BOOL Marking_SetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG uValue); +BOOL Marking_SetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pString); +BOOL Marking_Validate(ANSC_HANDLE hInsContext, char* pReturnParamName, ULONG* puLength); +ULONG Marking_Commit(ANSC_HANDLE hInsContext); +ULONG Marking_Rollback(ANSC_HANDLE hInsContext); + +/*********************************************************************** + + APIs for Object: + + X_RDK_WanManager.CPEInterface.{i}.PPP. + + * WanIfPPPCfg_GetParamUlongValue + * WanIfPPPCfg_SetParamUlongValue + * WanIfPPPCfg_GetParamStringValue + * WanIfPPPCfg_SetParamStringValue + * WanIfPPPCfg_GetParamBoolValue + * WanIfPPPCfg_SetParamBoolValue + * WanIfPPPCfg_Validate + * WanIfPPPCfg_Commit + * WanPPPIpCfg_Rollback + +***********************************************************************/ + +BOOL WanIfPPPCfg_GetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG* puLong); +BOOL WanIfPPPCfg_SetParamUlongValue(ANSC_HANDLE hInsContext, char* ParamName, ULONG uValue); +ULONG WanIfPPPCfg_GetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pValue, ULONG* pUlSize); +BOOL WanIfPPPCfg_SetParamStringValue(ANSC_HANDLE hInsContext, char* ParamName, char* pString); +ULONG WanIfPPPCfg_GetParamBoolValue(ANSC_HANDLE hInsContext, char* ParamName, BOOL* pBool); +BOOL WanIfPPPCfg_SetParamBoolValue(ANSC_HANDLE hInsContext, char* ParamName, BOOL bValue); +BOOL WanIfPPPCfg_Validate(ANSC_HANDLE hInsContext, char* ParamName, BOOL bValue); +ULONG WanIfPPPCfg_Commit(ANSC_HANDLE hInsContext); +ULONG WanIfPPPCfg_Rollback(ANSC_HANDLE hInsContext); + +#endif /* _WANMGR_DML_IFACE_APIS_H_ */ diff --git a/source/TR-181/middle_layer_src/wanmgr_plugin_main.c b/source/TR-181/middle_layer_src/wanmgr_plugin_main.c new file mode 100644 index 00000000..5f3613b1 --- /dev/null +++ b/source/TR-181/middle_layer_src/wanmgr_plugin_main.c @@ -0,0 +1,571 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2017 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + + +/*********************************************************************** + + module: plugin_main.c + + Implement COSA Data Model Library Init and Unload apis. + + --------------------------------------------------------------- + + author: + + COSA XML TOOL CODE GENERATOR 1.0 + + --------------------------------------------------------------- + + revision: + + 09/28/2011 initial revision. + +**********************************************************************/ + +#include "ansc_platform.h" +#include "ansc_load_library.h" +#include "cosa_plugin_api.h" +#include "ccsp_psm_helper.h" +#include "dmsb_tr181_psm_definitions.h" +#include "wanmgr_plugin_main.h" +#include "wanmgr_plugin_main_apis.h" +#include "wanmgr_dml_apis.h" +#include "wanmgr_dml_iface_apis.h" +#include "wanmgr_dml_dhcpv4.h" +#include "wanmgr_dml_dhcpv6.h" + +void * g_pDslhDmlAgent; +extern ANSC_HANDLE g_MessageBusHandle_Irep; +extern char g_SubSysPrefix_Irep[32]; +extern COSARepopulateTableProc g_COSARepopulateTable; + +#define THIS_PLUGIN_VERSION 1 + + +int ANSC_EXPORT_API WanManagerDmlInit(ULONG uMaxVersionSupported, void* hCosaPlugInfo) +{ + PCOSA_PLUGIN_INFO pPlugInfo = (PCOSA_PLUGIN_INFO )hCosaPlugInfo; + COSAGetParamValueByPathNameProc pGetParamValueByPathNameProc = (COSAGetParamValueByPathNameProc)NULL; + COSASetParamValueByPathNameProc pSetParamValueByPathNameProc = (COSASetParamValueByPathNameProc)NULL; + COSAGetParamValueStringProc pGetStringProc = (COSAGetParamValueStringProc )NULL; + COSAGetParamValueUlongProc pGetParamValueUlongProc = (COSAGetParamValueUlongProc )NULL; + COSAGetParamValueIntProc pGetParamValueIntProc = (COSAGetParamValueIntProc )NULL; + COSAGetParamValueBoolProc pGetParamValueBoolProc = (COSAGetParamValueBoolProc )NULL; + COSASetParamValueStringProc pSetStringProc = (COSASetParamValueStringProc )NULL; + COSASetParamValueUlongProc pSetParamValueUlongProc = (COSASetParamValueUlongProc )NULL; + COSASetParamValueIntProc pSetParamValueIntProc = (COSASetParamValueIntProc )NULL; + COSASetParamValueBoolProc pSetParamValueBoolProc = (COSASetParamValueBoolProc )NULL; + COSAGetInstanceNumbersProc pGetInstanceNumbersProc = (COSAGetInstanceNumbersProc )NULL; + + COSAGetCommonHandleProc pGetCHProc = (COSAGetCommonHandleProc )NULL; + COSAValidateHierarchyInterfaceProc + pValInterfaceProc = (COSAValidateHierarchyInterfaceProc)NULL; + COSAGetHandleProc pGetRegistryRootFolder = (COSAGetHandleProc )NULL; + COSAGetInstanceNumberByIndexProc + pGetInsNumberByIndexProc = (COSAGetInstanceNumberByIndexProc )NULL; + COSAGetHandleProc pGetMessageBusHandleProc = (COSAGetHandleProc )NULL; + COSAGetInterfaceByNameProc pGetInterfaceByNameProc = (COSAGetInterfaceByNameProc )NULL; + ULONG ret = 0; + + if ( uMaxVersionSupported < THIS_PLUGIN_VERSION ) + { + /* this version is not supported */ + return -1; + } + + pPlugInfo->uPluginVersion = THIS_PLUGIN_VERSION; + g_pDslhDmlAgent = pPlugInfo->hDmlAgent; + +/* + pGetCHProc = (COSAGetCommonHandleProc)pPlugInfo->AcquireFunction("COSAGetDiagPluginInfo"); + + if( pGetCHProc != NULL) + { + g_pCosaDiagPluginInfo = pGetCHProc(NULL); + } + else + { + goto EXIT; + } +*/ + pGetParamValueByPathNameProc = (COSAGetParamValueByPathNameProc)pPlugInfo->AcquireFunction("COSAGetParamValueByPathName"); + + if( pGetParamValueByPathNameProc != NULL) + { + g_GetParamValueByPathNameProc = pGetParamValueByPathNameProc; + } + else + { + goto EXIT; + } + + pSetParamValueByPathNameProc = (COSASetParamValueByPathNameProc)pPlugInfo->AcquireFunction("COSASetParamValueByPathName"); + + if( pSetParamValueByPathNameProc != NULL) + { + g_SetParamValueByPathNameProc = pSetParamValueByPathNameProc; + } + else + { + goto EXIT; + } + + pGetStringProc = (COSAGetParamValueStringProc)pPlugInfo->AcquireFunction("COSAGetParamValueString"); + + if( pGetStringProc != NULL) + { + g_GetParamValueString = pGetStringProc; + } + else + { + goto EXIT; + } + + pGetParamValueUlongProc = (COSAGetParamValueUlongProc)pPlugInfo->AcquireFunction("COSAGetParamValueUlong"); + + if( pGetParamValueUlongProc != NULL) + { + g_GetParamValueUlong = pGetParamValueUlongProc; + } + else + { + goto EXIT; + } + + + pGetParamValueIntProc = (COSAGetParamValueIntProc)pPlugInfo->AcquireFunction("COSAGetParamValueInt"); + + if( pGetParamValueIntProc != NULL) + { + g_GetParamValueInt = pGetParamValueIntProc; + } + else + { + goto EXIT; + } + + pGetParamValueBoolProc = (COSAGetParamValueBoolProc)pPlugInfo->AcquireFunction("COSAGetParamValueBool"); + + if( pGetParamValueBoolProc != NULL) + { + g_GetParamValueBool = pGetParamValueBoolProc; + } + else + { + goto EXIT; + } + + pSetStringProc = (COSASetParamValueStringProc)pPlugInfo->AcquireFunction("COSASetParamValueString"); + + if( pSetStringProc != NULL) + { + g_SetParamValueString = pSetStringProc; + } + else + { + goto EXIT; + } + + pSetParamValueUlongProc = (COSASetParamValueUlongProc)pPlugInfo->AcquireFunction("COSASetParamValueUlong"); + + if( pSetParamValueUlongProc != NULL) + { + g_SetParamValueUlong = pSetParamValueUlongProc; + } + else + { + goto EXIT; + } + + + pSetParamValueIntProc = (COSASetParamValueIntProc)pPlugInfo->AcquireFunction("COSASetParamValueInt"); + + if( pSetParamValueIntProc != NULL) + { + g_SetParamValueInt = pSetParamValueIntProc; + } + else + { + goto EXIT; + } + + pSetParamValueBoolProc = (COSASetParamValueBoolProc)pPlugInfo->AcquireFunction("COSASetParamValueBool"); + + if( pSetParamValueBoolProc != NULL) + { + g_SetParamValueBool = pSetParamValueBoolProc; + } + else + { + goto EXIT; + } + + pGetInstanceNumbersProc = (COSAGetInstanceNumbersProc)pPlugInfo->AcquireFunction("COSAGetInstanceNumbers"); + + if( pGetInstanceNumbersProc != NULL) + { + g_GetInstanceNumbers = pGetInstanceNumbersProc; + } + else + { + goto EXIT; + } + + pValInterfaceProc = (COSAValidateHierarchyInterfaceProc)pPlugInfo->AcquireFunction("COSAValidateHierarchyInterface"); + + if ( pValInterfaceProc ) + { + g_ValidateInterface = pValInterfaceProc; + } + else + { + goto EXIT; + } +/* +#ifndef _ANSC_WINDOWSNT +#ifdef _SOFTWAREMODULES_SUPPORT_NAF + CosaSoftwareModulesInit(hCosaPlugInfo); +#endif +#endif +*/ + pGetRegistryRootFolder = (COSAGetHandleProc)pPlugInfo->AcquireFunction("COSAGetRegistryRootFolder"); + + if ( pGetRegistryRootFolder != NULL ) + { + g_GetRegistryRootFolder = pGetRegistryRootFolder; + } + else + { + printf("!!! haha, catcha !!!\n"); + goto EXIT; + } + + pGetInsNumberByIndexProc = (COSAGetInstanceNumberByIndexProc)pPlugInfo->AcquireFunction("COSAGetInstanceNumberByIndex"); + + if ( pGetInsNumberByIndexProc != NULL ) + { + g_GetInstanceNumberByIndex = pGetInsNumberByIndexProc; + } + else + { + goto EXIT; + } + + pGetInterfaceByNameProc = (COSAGetInterfaceByNameProc)pPlugInfo->AcquireFunction("COSAGetInterfaceByName"); + + if ( pGetInterfaceByNameProc != NULL ) + { + g_GetInterfaceByName = pGetInterfaceByNameProc; + } + else + { + goto EXIT; + } + + g_pPnmCcdIf = g_GetInterfaceByName(g_pDslhDmlAgent, CCSP_CCD_INTERFACE_NAME); + + if ( !g_pPnmCcdIf ) + { + CcspTraceError(("g_pPnmCcdIf is NULL !\n")); + + goto EXIT; + } + + g_RegisterCallBackAfterInitDml = (COSARegisterCallBackAfterInitDmlProc)pPlugInfo->AcquireFunction("COSARegisterCallBackAfterInitDml"); + + if ( !g_RegisterCallBackAfterInitDml ) + { + goto EXIT; + } + + g_COSARepopulateTable = (COSARepopulateTableProc)pPlugInfo->AcquireFunction("COSARepopulateTable"); + + if ( !g_COSARepopulateTable ) + { + goto EXIT; + } + + /* Get Message Bus Handle */ + g_GetMessageBusHandle = (PFN_CCSPCCDM_APPLY_CHANGES)pPlugInfo->AcquireFunction("COSAGetMessageBusHandle"); + if ( g_GetMessageBusHandle == NULL ) + { + goto EXIT; + } + + g_MessageBusHandle = (ANSC_HANDLE)g_GetMessageBusHandle(g_pDslhDmlAgent); + if ( g_MessageBusHandle == NULL ) + { + goto EXIT; + } + g_MessageBusHandle_Irep = g_MessageBusHandle; + + /* Get Subsystem prefix */ + g_GetSubsystemPrefix = (COSAGetSubsystemPrefixProc)pPlugInfo->AcquireFunction("COSAGetSubsystemPrefix"); + if ( g_GetSubsystemPrefix != NULL ) + { + char* tmpSubsystemPrefix; + + if ( tmpSubsystemPrefix = g_GetSubsystemPrefix(g_pDslhDmlAgent) ) + { + AnscCopyString(g_SubSysPrefix_Irep, tmpSubsystemPrefix); + } + + /* retrieve the subsystem prefix */ + g_SubsystemPrefix = g_GetSubsystemPrefix(g_pDslhDmlAgent); + } + + /* register the back-end apis for the data model */ + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanManager_GetParamUlongValue", WanManager_GetParamUlongValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanManager_SetParamUlongValue", WanManager_SetParamUlongValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanManager_GetParamBoolValue", WanManager_GetParamBoolValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanManager_SetParamBoolValue", WanManager_SetParamBoolValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanManager_GetParamStringValue", WanManager_GetParamStringValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanManager_Commit", WanManager_Commit); + + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIf_GetEntryCount", WanIf_GetEntryCount); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIf_GetEntry", WanIf_GetEntry); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIf_GetParamStringValue", WanIf_GetParamStringValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIf_SetParamStringValue", WanIf_SetParamStringValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIf_Validate", WanIf_Validate); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIf_Commit", WanIf_Commit); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIf_Rollback", WanIf_Rollback); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfPhy_GetParamStringValue", WanIfPhy_GetParamStringValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfPhy_SetParamStringValue", WanIfPhy_SetParamStringValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfPhy_GetParamUlongValue", WanIfPhy_GetParamUlongValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfPhy_SetParamUlongValue", WanIfPhy_SetParamUlongValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfPhy_Validate", WanIfPhy_Validate); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfPhy_Commit", WanIfPhy_Commit); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfPhy_Rollback", WanIfPhy_Rollback); + + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfCfg_GetParamUlongValue", WanIfCfg_GetParamUlongValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfCfg_SetParamUlongValue", WanIfCfg_SetParamUlongValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfCfg_GetParamIntValue", WanIfCfg_GetParamIntValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfCfg_SetParamIntValue", WanIfCfg_SetParamIntValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfCfg_GetParamBoolValue", WanIfCfg_GetParamBoolValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfCfg_SetParamBoolValue", WanIfCfg_SetParamBoolValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfCfg_GetParamStringValue", WanIfCfg_GetParamStringValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfCfg_SetParamStringValue", WanIfCfg_SetParamStringValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfCfg_Validate", WanIfCfg_Validate); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfCfg_Commit", WanIfCfg_Commit); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfCfg_Rollback", WanIfCfg_Rollback); + + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfDynTrigger_GetParamUlongValue", WanIfDynTrigger_GetParamUlongValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfDynTrigger_SetParamUlongValue", WanIfDynTrigger_SetParamUlongValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfDynTrigger_GetParamBoolValue", WanIfDynTrigger_GetParamBoolValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfDynTrigger_SetParamBoolValue", WanIfDynTrigger_SetParamBoolValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfDynTrigger_Validate", WanIfDynTrigger_Validate); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfDynTrigger_Commit", WanIfDynTrigger_Commit); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfDynTrigger_Rollback", WanIfDynTrigger_Rollback); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfIpCfg_GetParamUlongValue", WanIfIpCfg_GetParamUlongValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfIpCfg_SetParamUlongValue", WanIfIpCfg_SetParamUlongValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfIpCfg_GetParamStringValue", WanIfIpCfg_GetParamStringValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfIpCfg_SetParamStringValue", WanIfIpCfg_SetParamStringValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfIpCfg_Validate", WanIfIpCfg_Validate); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfIpCfg_Commit", WanIfIpCfg_Commit); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfIpCfg_Rollback", WanIfIpCfg_Rollback); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfMapt_GetParamUlongValue", WanIfMapt_GetParamUlongValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfMapt_SetParamUlongValue", WanIfMapt_SetParamUlongValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfMapt_GetParamStringValue", WanIfMapt_GetParamStringValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfMapt_SetParamStringValue", WanIfMapt_SetParamStringValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfMapt_Validate", WanIfMapt_Validate); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfMapt_Commit", WanIfMapt_Commit); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfMapt_Rollback", WanIfMapt_Rollback); + + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfPPPCfg_GetParamUlongValue", WanIfPPPCfg_GetParamUlongValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfPPPCfg_SetParamUlongValue", WanIfPPPCfg_SetParamUlongValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfPPPCfg_GetParamStringValue", WanIfPPPCfg_GetParamStringValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfPPPCfg_SetParamStringValue", WanIfPPPCfg_SetParamStringValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfPPPCfg_GetParamBoolValue", WanIfPPPCfg_GetParamBoolValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfPPPCfg_SetParamBoolValue", WanIfPPPCfg_SetParamBoolValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfPPPCfg_Validate", WanIfPPPCfg_Validate); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfPPPCfg_Rollback", WanIfPPPCfg_Rollback); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfPPPCfg_Commit", WanIfPPPCfg_Commit); + + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfDSLite_GetParamUlongValue", WanIfDSLite_GetParamUlongValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfDSLite_SetParamUlongValue", WanIfDSLite_SetParamUlongValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfDSLite_GetParamStringValue", WanIfDSLite_GetParamStringValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfDSLite_SetParamStringValue", WanIfDSLite_SetParamStringValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfDSLite_Commit", WanIfDSLite_Commit); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfDSLite_Rollback", WanIfDSLite_Rollback); + + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Marking_GetEntryCount", Marking_GetEntryCount); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Marking_GetEntry", Marking_GetEntry); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Marking_AddEntry", Marking_AddEntry); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Marking_DelEntry", Marking_DelEntry); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Marking_GetParamUlongValue", Marking_GetParamUlongValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Marking_GetParamStringValue", Marking_GetParamStringValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Marking_GetParamIntValue", Marking_GetParamIntValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Marking_SetParamIntValue", Marking_SetParamIntValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Marking_SetParamUlongValue", Marking_SetParamUlongValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Marking_SetParamStringValue", Marking_SetParamStringValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Marking_Validate", Marking_Validate); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Marking_Commit", Marking_Commit); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Marking_Rollback", Marking_Rollback); + + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfValidation_GetParamBoolValue", WanIfValidation_GetParamBoolValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfValidation_SetParamBoolValue", WanIfValidation_SetParamBoolValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfValidation_Validate", WanIfValidation_Validate); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfValidation_Commit", WanIfValidation_Commit); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "WanIfValidation_Rollback", WanIfValidation_Rollback); + + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "DHCPv6_GetParamBoolValue", DHCPv6_GetParamBoolValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "DHCPv6_GetParamIntValue", DHCPv6_GetParamIntValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "DHCPv6_GetParamUlongValue", DHCPv6_GetParamUlongValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "DHCPv6_GetParamStringValue", DHCPv6_GetParamStringValue); + + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Client3_GetEntryCount", Client3_GetEntryCount); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Client3_GetEntry", Client3_GetEntry); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Client3_AddEntry", Client3_AddEntry); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Client3_DelEntry", Client3_DelEntry); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Client3_GetParamBoolValue", Client3_GetParamBoolValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Client3_GetParamIntValue", Client3_GetParamIntValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Client3_GetParamUlongValue", Client3_GetParamUlongValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Client3_GetParamStringValue", Client3_GetParamStringValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Client3_SetParamBoolValue", Client3_SetParamBoolValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Client3_SetParamIntValue", Client3_SetParamIntValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Client3_SetParamUlongValue", Client3_SetParamUlongValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Client3_SetParamStringValue", Client3_SetParamStringValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Client3_Validate", Client3_Validate); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Client3_Commit", Client3_Commit); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Client3_Rollback", Client3_Rollback); + + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Server2_GetEntryCount", Server2_GetEntryCount); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Server2_GetEntry", Server2_GetEntry); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Server2_IsUpdated", Server2_IsUpdated); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Server2_Synchronize", Server2_Synchronize); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Server2_GetParamBoolValue", Server2_GetParamBoolValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Server2_GetParamIntValue", Server2_GetParamIntValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Server2_GetParamUlongValue", Server2_GetParamUlongValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Server2_GetParamStringValue", Server2_GetParamStringValue); + + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "SentOption1_GetEntryCount", SentOption1_GetEntryCount); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "SentOption1_GetEntry", SentOption1_GetEntry); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "SentOption1_AddEntry", SentOption1_AddEntry); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "SentOption1_DelEntry", SentOption1_DelEntry); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "SentOption1_GetParamBoolValue", SentOption1_GetParamBoolValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "SentOption1_GetParamIntValue", SentOption1_GetParamIntValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "SentOption1_GetParamUlongValue", SentOption1_GetParamUlongValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "SentOption1_GetParamStringValue", SentOption1_GetParamStringValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "SentOption1_SetParamBoolValue", SentOption1_SetParamBoolValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "SentOption1_SetParamIntValue", SentOption1_SetParamIntValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "SentOption1_SetParamUlongValue", SentOption1_SetParamUlongValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "SentOption1_SetParamStringValue", SentOption1_SetParamStringValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "SentOption1_Validate", SentOption1_Validate); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "SentOption1_Commit", SentOption1_Commit); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "SentOption1_Rollback", SentOption1_Rollback); + + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "DHCPv4_GetParamBoolValue", DHCPv4_GetParamBoolValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "DHCPv4_GetParamIntValue", DHCPv4_GetParamIntValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "DHCPv4_GetParamUlongValue", DHCPv4_GetParamUlongValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "DHCPv4_GetParamStringValue", DHCPv4_GetParamStringValue); + + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Client_GetEntryCount", Client_GetEntryCount); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Client_GetEntry", Client_GetEntry); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Client_AddEntry", Client_AddEntry); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Client_DelEntry", Client_DelEntry); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Client_GetParamBoolValue", Client_GetParamBoolValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Client_GetParamIntValue", Client_GetParamIntValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Client_GetParamUlongValue", Client_GetParamUlongValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Client_GetParamStringValue", Client_GetParamStringValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Client_SetParamBoolValue", Client_SetParamBoolValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Client_SetParamIntValue", Client_SetParamIntValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Client_SetParamUlongValue", Client_SetParamUlongValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Client_SetParamStringValue", Client_SetParamStringValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Client_Validate", Client_Validate); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Client_Commit", Client_Commit); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "Client_Rollback", Client_Rollback); + + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "SentOption_GetEntryCount", SentOption_GetEntryCount); + + + + /* Create backend framework */ + g_pWanMgrBE = (WANMGR_BACKEND_OBJ*)BackEndManagerCreate(); + + if ( g_pWanMgrBE && g_pWanMgrBE->Initialize ) + { + g_pWanMgrBE->hCosaPluginInfo = pPlugInfo; + + g_pWanMgrBE->Initialize ((ANSC_HANDLE)g_pWanMgrBE); + } + + + + + return 0; + +EXIT: + return -1; +} + +BOOL ANSC_EXPORT_API COSA_IsObjectSupported(char* pObjName) +{ + + return TRUE; +} + +void ANSC_EXPORT_API COSA_Unload(void) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + + /* unload the memory here */ + + returnStatus = BackEndManagerRemove(g_pWanMgrBE); + + if ( returnStatus == ANSC_STATUS_SUCCESS ) + { + g_pWanMgrBE = NULL; + } + else + { + /* print error trace*/ + g_pWanMgrBE = NULL; + } +} + + + +void ANSC_EXPORT_API COSA_MemoryCheck(void) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PCOSA_PLUGIN_INFO pPlugInfo = (PCOSA_PLUGIN_INFO)g_pWanMgrBE->hCosaPluginInfo; + + /* unload the memory here */ + + returnStatus = BackEndManagerRemove(g_pWanMgrBE); + + if ( returnStatus == ANSC_STATUS_SUCCESS ) + { + g_pWanMgrBE = NULL; + } + else + { + g_pWanMgrBE = NULL; + } + + + g_pWanMgrBE = (WANMGR_BACKEND_OBJ*)BackEndManagerCreate(); + + if ( g_pWanMgrBE && g_pWanMgrBE->Initialize ) + { + g_pWanMgrBE->hCosaPluginInfo = pPlugInfo; + + g_pWanMgrBE->Initialize ((ANSC_HANDLE)g_pWanMgrBE); + } +} diff --git a/source/TR-181/middle_layer_src/wanmgr_plugin_main.h b/source/TR-181/middle_layer_src/wanmgr_plugin_main.h new file mode 100644 index 00000000..17af1bf3 --- /dev/null +++ b/source/TR-181/middle_layer_src/wanmgr_plugin_main.h @@ -0,0 +1,94 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2017 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + + +/********************************************************************** + + module: plugin_main.h + + For COSA Library development. + + --------------------------------------------------------------- + + description: + + This header file defines the exported apis for COSA Library plugin. + + --------------------------------------------------------------- + + environment: + + platform independent + + --------------------------------------------------------------- + + author: + + Bin Zhu + + --------------------------------------------------------------- + + revision: + + 12/12/2010 initial revision. + +**********************************************************************/ + + +#ifndef _WANMGR_PLUGIN_MAIN_H_ +#define _WANMGR_PLUGIN_MAIN_H_ + + +#if (defined _ANSC_WINDOWSNT) || (defined _ANSC_WINDOWS9X) + +#ifdef _ALMIB_EXPORTS +#define ANSC_EXPORT_API __declspec(dllexport) +#else +#define ANSC_EXPORT_API __declspec(dllimport) +#endif + +#endif + +#ifdef _ANSC_LINUX +#define ANSC_EXPORT_API +#endif + +#ifdef __cplusplus +extern "C"{ +#endif + +/*************************************************************************** + * + * COSA stands for "Cisco Open Service Architecture" + * + ***************************************************************************/ +int ANSC_EXPORT_API WanManagerDmlInit( + ULONG uMaxVersionSupported, + void* hCosaPlugInfo /* PCOSA_PLUGIN_INFO passed in by the caller */ + ); + +BOOL ANSC_EXPORT_API COSA_IsObjectSupported(char* pObjName); + +void ANSC_EXPORT_API COSA_Unload(void); + +#ifdef __cplusplus +} +#endif + +#endif //_WANMGR_PLUGIN_MAIN_H_ diff --git a/source/TR-181/middle_layer_src/wanmgr_plugin_main_apis.c b/source/TR-181/middle_layer_src/wanmgr_plugin_main_apis.c new file mode 100644 index 00000000..ddd1cbce --- /dev/null +++ b/source/TR-181/middle_layer_src/wanmgr_plugin_main_apis.c @@ -0,0 +1,237 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2015 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +/********************************************************************** + Copyright [2014] [Cisco Systems, Inc.] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +**********************************************************************/ + + +/*********************************************************************** + + module: plugin_main_apis.c + + Implement COSA Data Model Library Init and Unload apis. + This files will hold all data in it. + --------------------------------------------------------------- + + description: + + This module implements the advanced state-access functions + of the Dslh Var Record Object. + + * BackEndManagerCreate + * BackEndManagerInitialize + * BackEndManagerRemove + --------------------------------------------------------------- + + author: + + COSA XML TOOL CODE GENERATOR 1.0 + + --------------------------------------------------------------- + + revision: + + 01/11/2011 initial revision. + +**********************************************************************/ + +//#include "dml_tr181_custom_cfg.h" +#include "wanmgr_plugin_main_apis.h" + +/*PCOSA_DIAG_PLUGIN_INFO g_pCosaDiagPluginInfo;*/ +COSAGetParamValueByPathNameProc g_GetParamValueByPathNameProc; +COSASetParamValueByPathNameProc g_SetParamValueByPathNameProc; +COSAGetParamValueStringProc g_GetParamValueString; +COSAGetParamValueUlongProc g_GetParamValueUlong; +COSAGetParamValueIntProc g_GetParamValueInt; +COSAGetParamValueBoolProc g_GetParamValueBool; +COSASetParamValueStringProc g_SetParamValueString; +COSASetParamValueUlongProc g_SetParamValueUlong; +COSASetParamValueIntProc g_SetParamValueInt; +COSASetParamValueBoolProc g_SetParamValueBool; +COSAGetInstanceNumbersProc g_GetInstanceNumbers; + +COSAValidateHierarchyInterfaceProc g_ValidateInterface; +COSAGetHandleProc g_GetRegistryRootFolder; +COSAGetInstanceNumberByIndexProc g_GetInstanceNumberByIndex; +COSAGetInterfaceByNameProc g_GetInterfaceByName; +COSAGetHandleProc g_GetMessageBusHandle; +COSAGetSubsystemPrefixProc g_GetSubsystemPrefix; +PCCSP_CCD_INTERFACE g_pPnmCcdIf; +ANSC_HANDLE g_MessageBusHandle; +char* g_SubsystemPrefix; +COSARegisterCallBackAfterInitDmlProc g_RegisterCallBackAfterInitDml; +COSARepopulateTableProc g_COSARepopulateTable; + +/********************************************************************** + + caller: owner of the object + + prototype: + + ANSC_HANDLE BackEndManagerCreate(VOID); + + description: + + This function constructs cosa datamodel object and return handle. + + argument: + + return: newly created qos object. + +**********************************************************************/ + +ANSC_HANDLE BackEndManagerCreate(VOID) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + WANMGR_BACKEND_OBJ* pMyObject = (WANMGR_BACKEND_OBJ*)NULL; + + /* + * We create object by first allocating memory for holding the variables and member functions. + */ + pMyObject = (WANMGR_BACKEND_OBJ*)AnscAllocateMemory(sizeof(WANMGR_BACKEND_OBJ)); + if ( pMyObject == NULL ) + { + return (ANSC_HANDLE)NULL; + } + + /* + * Initialize the common variables and functions for a container object. + */ + pMyObject->Oid = DATAMODEL_BASE_OID; + pMyObject->Create = BackEndManagerCreate; + pMyObject->Remove = BackEndManagerRemove; + pMyObject->Initialize = BackEndManagerInitialize; + + /*pMyObject->Initialize ((ANSC_HANDLE)pMyObject);*/ + + return (ANSC_HANDLE)pMyObject; +} + +/********************************************************************** + + caller: self + + prototype: + + ANSC_STATUS BackEndManagerInitialize(ANSC_HANDLE hThisObject); + + description: + + This function initiate cosa manager object and return handle. + + argument: ANSC_HANDLE hThisObject + This handle is actually the pointer of this object + itself. + + return: operation status. + +**********************************************************************/ + +ANSC_STATUS BackEndManagerInitialize(ANSC_HANDLE hThisObject) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + WANMGR_BACKEND_OBJ* pMyObject = (WANMGR_BACKEND_OBJ*)hThisObject; + + if (pMyObject == NULL) + { + AnscTraceError(("%s:%d:: Pointer is null!!\n", __FUNCTION__, __LINE__)); + return ANSC_STATUS_FAILURE; + } + +#ifdef _COSA_SIM_ + pMyObject->has_moca_slap = 0; + pMyObject->has_wifi_slap = 0; +#endif + + AnscTraceWarning(("%s...\n", __FUNCTION__)); + + + //Wan Manager Configuration + WanMgr_WanConfigInit(); + + pMyObject->hDhcpv4 = (ANSC_HANDLE)WanMgr_Dhcpv4Create(); + AnscTraceWarning((" WanMgr_Dhcpv4Create done!\n")); + + pMyObject->hDhcpv6 = (ANSC_HANDLE)WanMgr_Dhcpv6Create(); + AnscTraceWarning((" WanMgr_Dhcpv6Create done!\n")); + + + + return returnStatus; +} + +/********************************************************************** + + caller: self + + prototype: + + ANSC_STATUS BackEndManagerRemove(ANSC_HANDLE hThisObject); + + description: + + This function remove cosa manager object and return handle. + + argument: ANSC_HANDLE hThisObject + This handle is actually the pointer of this object + itself. + + return: operation status. + +**********************************************************************/ + +ANSC_STATUS BackEndManagerRemove(ANSC_HANDLE hThisObject) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + WANMGR_BACKEND_OBJ* pMyObject = (WANMGR_BACKEND_OBJ*)hThisObject; + + if (pMyObject == NULL) + { + AnscTraceError(("%s:%d:: Pointer is null!!\n", __FUNCTION__, __LINE__)); + return ANSC_STATUS_FAILURE; + } + if ( pMyObject->hDhcpv4 ) + { + WanMgr_Dhcpv4Remove((ANSC_HANDLE)pMyObject->hDhcpv4); + } + + if ( pMyObject->hDhcpv6 ) + { + WanMgr_Dhcpv6Remove((ANSC_HANDLE)pMyObject->hDhcpv6); + } + + /* Remove self */ + AnscFreeMemory((ANSC_HANDLE)pMyObject); + + return returnStatus; +} diff --git a/source/TR-181/middle_layer_src/wanmgr_plugin_main_apis.h b/source/TR-181/middle_layer_src/wanmgr_plugin_main_apis.h new file mode 100644 index 00000000..24066b93 --- /dev/null +++ b/source/TR-181/middle_layer_src/wanmgr_plugin_main_apis.h @@ -0,0 +1,140 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2015 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +/********************************************************************** + Copyright [2014] [Cisco Systems, Inc.] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +**********************************************************************/ + + +/************************************************************************** + + module: plugin_main_apis.h + + For COSA Data Model Library Development + + ------------------------------------------------------------------- + + description: + + This file defines the apis for objects to support Data Model Library. + + ------------------------------------------------------------------- + + + author: + + COSA XML TOOL CODE GENERATOR 1.0 + + ------------------------------------------------------------------- + + revision: + + 01/11/2011 initial revision. + +**************************************************************************/ + + +#ifndef _WANMGR_PLUGIN_MAIN_APIS_H_ +#define _WANMGR_PLUGIN_MAIN_APIS_H_ + +#include "ansc_platform.h" +#include "wanmgr_rdkbus_common.h" +#include "dslh_cpeco_interface.h" + +// include files needed by diagnostic +/* +#include "dslh_definitions_diagnostics.h" +#include "bbhm_diag_lib.h" +*/ +#include "dslh_dmagnt_interface.h" +#include "ccsp_ifo_ccd.h" + +/* +#include "bbhm_diageo_interface.h" +#include "bbhm_diagip_interface.h" +#include "bbhm_diagit_interface.h" +#include "bbhm_diagns_interface.h" +#include "bbhm_download_interface.h" +#include "bbhm_upload_interface.h" +#include "bbhm_udpecho_interface.h" +*/ + +/*extern PCOSA_DIAG_PLUGIN_INFO g_pCosaDiagPluginInfo;*/ +extern COSAGetParamValueByPathNameProc g_GetParamValueByPathNameProc; +extern COSASetParamValueByPathNameProc g_SetParamValueByPathNameProc; +extern COSAGetParamValueStringProc g_GetParamValueString; +extern COSAGetParamValueUlongProc g_GetParamValueUlong; +extern COSAGetParamValueIntProc g_GetParamValueInt; +extern COSAGetParamValueBoolProc g_GetParamValueBool; +extern COSASetParamValueStringProc g_SetParamValueString; +extern COSASetParamValueUlongProc g_SetParamValueUlong; +extern COSASetParamValueIntProc g_SetParamValueInt; +extern COSASetParamValueBoolProc g_SetParamValueBool; +extern COSAGetInstanceNumbersProc g_GetInstanceNumbers; + +extern COSAValidateHierarchyInterfaceProc g_ValidateInterface; +extern COSAGetHandleProc g_GetRegistryRootFolder; +extern COSAGetInstanceNumberByIndexProc g_GetInstanceNumberByIndex; +extern COSAGetHandleProc g_GetMessageBusHandle; +extern COSAGetSubsystemPrefixProc g_GetSubsystemPrefix; +extern COSAGetInterfaceByNameProc g_GetInterfaceByName; +extern PCCSP_CCD_INTERFACE g_pPnmCcdIf; +extern ANSC_HANDLE g_MessageBusHandle; +extern char* g_SubsystemPrefix; +extern COSARegisterCallBackAfterInitDmlProc g_RegisterCallBackAfterInitDml; + +/* The OID for all objects s*/ +#define DATAMODEL_BASE_OID 0 +#define DATAMODEL_CM_OID 32 +#define DATAMODEL_RDKCENTRAL_CM_OID 42 +#define WAN_DHCPV6_DATA_OID 25 +#define WAN_DHCPV4_DATA_OID 2 + + +typedef struct _WANMGR_BACKEND_OBJ_ +{ + BASE_CONTENT; + PCOSA_PLUGIN_INFO hCosaPluginInfo; + ANSC_HANDLE hDhcpv6; + ANSC_HANDLE hDhcpv4; +#ifdef _COSA_SIM_ + ULONG has_wifi_slap; + ULONG has_moca_slap; +#endif +} WANMGR_BACKEND_OBJ; + +WANMGR_BACKEND_OBJ* g_pWanMgrBE; + +ANSC_HANDLE BackEndManagerCreate(VOID); +ANSC_STATUS BackEndManagerInitialize(ANSC_HANDLE hThisObject); +ANSC_STATUS BackEndManagerRemove(ANSC_HANDLE hThisObject); + +#endif //_WANMGR_PLUGIN_MAIN_APIS_H_ diff --git a/source/TR-181/middle_layer_src/wanmgr_rdkbus_apis.c b/source/TR-181/middle_layer_src/wanmgr_rdkbus_apis.c new file mode 100644 index 00000000..8ee5db49 --- /dev/null +++ b/source/TR-181/middle_layer_src/wanmgr_rdkbus_apis.c @@ -0,0 +1,1473 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2019 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +/********************************************************************** + Copyright [2014] [Cisco Systems, Inc.] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +**********************************************************************/ + +//!!! This code assumes that all data structures are the SAME in middle-layer APIs and HAL layer APIs +//!!! So it uses casting from one to the other +#include "wanmgr_rdkbus_apis.h" +#include "dmsb_tr181_psm_definitions.h" +#include "wanmgr_data.h" +#include "wanmgr_net_utils.h" +// +#define PSM_ENABLE_STRING_TRUE "TRUE" +#define PSM_ENABLE_STRING_FALSE "FALSE" +#define PPP_LINKTYPE_PPPOA "PPPoA" +#define PPP_LINKTYPE_PPPOE "PPPoE" + +#define DATA_SKB_MARKING_LOCATION "/tmp/skb_marking.conf" +extern char g_Subsystem[32]; +extern ANSC_HANDLE bus_handle; + +#define _PSM_READ_PARAM(_PARAM_NAME) { \ + _ansc_memset(param_name, 0, sizeof(param_name)); \ + _ansc_sprintf(param_name, _PARAM_NAME, instancenum); \ + retPsmGet = PSM_Get_Record_Value2(bus_handle,g_Subsystem, param_name, NULL, ¶m_value); \ + if (retPsmGet != CCSP_SUCCESS) { \ + AnscTraceFlow(("%s Error %d reading %s %s\n", __FUNCTION__, retPsmGet, param_name, param_value));\ + } \ + else { \ + /*AnscTraceFlow(("%s: retPsmGet == CCSP_SUCCESS reading %s = \n%s\n", __FUNCTION__,param_name, param_value)); */\ + } \ +} + +#define _PSM_WRITE_PARAM(_PARAM_NAME) { \ + _ansc_sprintf(param_name, _PARAM_NAME, instancenum); \ + retPsmSet = PSM_Set_Record_Value2(bus_handle,g_Subsystem, param_name, ccsp_string, param_value); \ + if (retPsmSet != CCSP_SUCCESS) { \ + AnscTraceFlow(("%s Error %d writing %s %s\n", __FUNCTION__, retPsmSet, param_name, param_value));\ + } \ + else \ + { \ + /*AnscTraceFlow(("%s: retPsmSet == CCSP_SUCCESS writing %s = %s \n", __FUNCTION__,param_name,param_value)); */\ + } \ + _ansc_memset(param_name, 0, sizeof(param_name)); \ + _ansc_memset(param_value, 0, sizeof(param_value)); \ +} + + +static int get_Wan_Interface_ParametersFromPSM(ULONG instancenum, DML_WAN_IFACE* p_Interface) +{ + int retPsmGet = CCSP_SUCCESS; + char *param_value= NULL; + char param_name[256]= {0}; + + p_Interface->uiInstanceNumber = instancenum; + + _PSM_READ_PARAM(PSM_WANMANAGER_IF_ENABLE); + if (retPsmGet == CCSP_SUCCESS) + { + if(strcmp(param_value, PSM_ENABLE_STRING_TRUE) == 0) + { + p_Interface->Wan.Enable = TRUE; + } + else + { + p_Interface->Wan.Enable = FALSE; + } + ((CCSP_MESSAGE_BUS_INFO *)bus_handle)->freefunc(param_value); + } + else + { + p_Interface->Wan.Enable = FALSE; + } + + _PSM_READ_PARAM(PSM_WANMANAGER_IF_NAME); + if (retPsmGet == CCSP_SUCCESS) + { + AnscCopyString(p_Interface->Name, param_value); + AnscCopyString(p_Interface->Wan.Name, param_value); + ((CCSP_MESSAGE_BUS_INFO *)bus_handle)->freefunc(param_value); + } + + _PSM_READ_PARAM(PSM_WANMANAGER_IF_DISPLAY_NAME); + if (retPsmGet == CCSP_SUCCESS) + { + AnscCopyString(p_Interface->DisplayName, param_value); + ((CCSP_MESSAGE_BUS_INFO *)bus_handle)->freefunc(param_value); + } + + _PSM_READ_PARAM(PSM_WANMANAGER_IF_TYPE); + if (retPsmGet == CCSP_SUCCESS) + { + _ansc_sscanf(param_value, "%d", &(p_Interface->Wan.Type)); + ((CCSP_MESSAGE_BUS_INFO *)bus_handle)->freefunc(param_value); + } + + _PSM_READ_PARAM(PSM_WANMANAGER_IF_PRIORITY); + if (retPsmGet == CCSP_SUCCESS) + { + _ansc_sscanf(param_value, "%d", &(p_Interface->Wan.Priority)); + ((CCSP_MESSAGE_BUS_INFO *)bus_handle)->freefunc(param_value); + } + + _PSM_READ_PARAM(PSM_WANMANAGER_IF_SELECTIONTIMEOUT); + if (retPsmGet == CCSP_SUCCESS) + { + _ansc_sscanf(param_value, "%d", &(p_Interface->Wan.SelectionTimeout)); + ((CCSP_MESSAGE_BUS_INFO *)bus_handle)->freefunc(param_value); + } + + _PSM_READ_PARAM(PSM_WANMANAGER_IF_WAN_ENABLE_MAPT); + if (retPsmGet == CCSP_SUCCESS) + { + if(strcmp(param_value, PSM_ENABLE_STRING_TRUE) == 0) + { + p_Interface->Wan.EnableMAPT = TRUE; + } + else + { + p_Interface->Wan.EnableMAPT = FALSE; + } + ((CCSP_MESSAGE_BUS_INFO *)bus_handle)->freefunc(param_value); + } + else + { + p_Interface->Wan.EnableMAPT = FALSE; + } + + _PSM_READ_PARAM(PSM_WANMANAGER_IF_WAN_ENABLE_DSLITE); + if (retPsmGet == CCSP_SUCCESS) + { + if(strcmp(param_value, PSM_ENABLE_STRING_TRUE) == 0) + { + p_Interface->Wan.EnableDSLite = TRUE; + } + else + { + p_Interface->Wan.EnableDSLite = FALSE; + } + ((CCSP_MESSAGE_BUS_INFO *)bus_handle)->freefunc(param_value); + } + else + { + p_Interface->Wan.EnableDSLite = FALSE; + } + + _PSM_READ_PARAM(PSM_WANMANAGER_IF_WAN_ENABLE_IPOE); + if (retPsmGet == CCSP_SUCCESS) + { + if(strcmp(param_value, PSM_ENABLE_STRING_TRUE) == 0) + { + p_Interface->Wan.EnableIPoE = TRUE; + } + else + { + p_Interface->Wan.EnableIPoE = FALSE; + } + ((CCSP_MESSAGE_BUS_INFO *)bus_handle)->freefunc(param_value); + } + else + { + p_Interface->Wan.EnableIPoE = FALSE; + } + + _PSM_READ_PARAM(PSM_WANMANAGER_IF_WAN_VALIDATION_DISCOVERY_OFFER); + if (retPsmGet == CCSP_SUCCESS) + { + if(strcmp(param_value, PSM_ENABLE_STRING_TRUE) == 0) + { + p_Interface->Wan.Validation.DiscoverOffer = TRUE; + } + else + { + p_Interface->Wan.Validation.DiscoverOffer = FALSE; + } + ((CCSP_MESSAGE_BUS_INFO *)bus_handle)->freefunc(param_value); + } + else + { + p_Interface->Wan.Validation.DiscoverOffer = FALSE; + } + + _PSM_READ_PARAM(PSM_WANMANAGER_IF_WAN_VALIDATION_SOLICIT_ADVERTISE); + if (retPsmGet == CCSP_SUCCESS) + { + if(strcmp(param_value, PSM_ENABLE_STRING_TRUE) == 0) + { + p_Interface->Wan.Validation.SolicitAdvertise = TRUE; + } + else + { + p_Interface->Wan.Validation.SolicitAdvertise = FALSE; + } + ((CCSP_MESSAGE_BUS_INFO *)bus_handle)->freefunc(param_value); + } + else + { + p_Interface->Wan.Validation.SolicitAdvertise = FALSE; + } + + _PSM_READ_PARAM(PSM_WANMANAGER_IF_WAN_VALIDATION_RS_RA); + if (retPsmGet == CCSP_SUCCESS) + { + if(strcmp(param_value, PSM_ENABLE_STRING_TRUE) == 0) + { + p_Interface->Wan.Validation.RS_RA = TRUE; + } + else + { + p_Interface->Wan.Validation.RS_RA = FALSE; + } + ((CCSP_MESSAGE_BUS_INFO *)bus_handle)->freefunc(param_value); + } + else + { + p_Interface->Wan.Validation.RS_RA = FALSE; + } + + _PSM_READ_PARAM(PSM_WANMANAGER_IF_WAN_VALIDATION_PADI_PADO); + if (retPsmGet == CCSP_SUCCESS) + { + if(strcmp(param_value, PSM_ENABLE_STRING_TRUE) == 0) + { + p_Interface->Wan.Validation.PadiPado = TRUE; + } + else + { + p_Interface->Wan.Validation.PadiPado = FALSE; + } + ((CCSP_MESSAGE_BUS_INFO *)bus_handle)->freefunc(param_value); + } + else + { + p_Interface->Wan.Validation.PadiPado = FALSE; + } + + _PSM_READ_PARAM(PSM_WANMANAGER_IF_DYNTRIGGERENABLE); + if (retPsmGet == CCSP_SUCCESS) + { + if(strcmp(param_value, PSM_ENABLE_STRING_TRUE) == 0) + { + p_Interface->DynamicTrigger.Enable = TRUE; + } + else + { + p_Interface->DynamicTrigger.Enable = FALSE; + } + ((CCSP_MESSAGE_BUS_INFO *)bus_handle)->freefunc(param_value); + } + _PSM_READ_PARAM(PSM_WANMANAGER_IF_WAN_PPP_ENABLE); + if (retPsmGet == CCSP_SUCCESS) + { + if(strcmp(param_value, PSM_ENABLE_STRING_TRUE) == 0) + { + p_Interface->PPP.Enable = TRUE; + } + else + { + p_Interface->PPP.Enable = FALSE; + } + ((CCSP_MESSAGE_BUS_INFO *)bus_handle)->freefunc(param_value); + } + else + { + p_Interface->PPP.Enable = FALSE; + } + + _PSM_READ_PARAM(PSM_WANMANAGER_IF_WAN_PPP_IPCP_ENABLE); + if (retPsmGet == CCSP_SUCCESS) + { + if(strcmp(param_value, PSM_ENABLE_STRING_TRUE) == 0) + { + p_Interface->PPP.IPCPEnable = TRUE; + } + else + { + p_Interface->PPP.IPCPEnable = FALSE; + } + ((CCSP_MESSAGE_BUS_INFO *)bus_handle)->freefunc(param_value); + } + else + { + p_Interface->PPP.IPCPEnable = FALSE; + } + + _PSM_READ_PARAM(PSM_WANMANAGER_IF_WAN_PPP_IPV6CP_ENABLE); + if (retPsmGet == CCSP_SUCCESS) + { + if(strcmp(param_value, PSM_ENABLE_STRING_TRUE) == 0) + { + p_Interface->PPP.IPV6CPEnable = TRUE; + } + else + { + p_Interface->PPP.IPV6CPEnable = FALSE; + } + ((CCSP_MESSAGE_BUS_INFO *)bus_handle)->freefunc(param_value); + } + else + { + p_Interface->PPP.IPV6CPEnable = FALSE; + } + + _PSM_READ_PARAM(PSM_WANMANAGER_IF_WAN_PPP_LINKTYPE); + if (retPsmGet == CCSP_SUCCESS) + { + if(strcmp(param_value, PPP_LINKTYPE_PPPOA) == 0) + { + p_Interface->PPP.LinkType = WAN_IFACE_PPP_LINK_TYPE_PPPoA; + } + else if(strcmp(param_value, PPP_LINKTYPE_PPPOE) == 0) + { + p_Interface->PPP.LinkType = WAN_IFACE_PPP_LINK_TYPE_PPPoE; + } + ((CCSP_MESSAGE_BUS_INFO *)bus_handle)->freefunc(param_value); + } + else + { + p_Interface->PPP.LinkType = WAN_IFACE_PPP_LINK_TYPE_PPPoA; + } + + _PSM_READ_PARAM(PSM_WANMANAGER_IF_DYNTRIGGERDELAY); + if (retPsmGet == CCSP_SUCCESS) + { + _ansc_sscanf(param_value, "%d", &(p_Interface->DynamicTrigger.Delay)); + ((CCSP_MESSAGE_BUS_INFO *)bus_handle)->freefunc(param_value); + } + + return ANSC_STATUS_SUCCESS; +} + +static int write_Wan_Interface_ParametersFromPSM(ULONG instancenum, DML_WAN_IFACE* p_Interface) +{ + int retPsmSet = CCSP_SUCCESS; + char param_name[256] = {0}; + char param_value[256] = {0}; + + memset(param_value, 0, sizeof(param_value)); + memset(param_name, 0, sizeof(param_name)); + + if(p_Interface->Wan.Enable) + { + _ansc_sprintf(param_value, "TRUE"); + } + else + { + _ansc_sprintf(param_value, "FALSE"); + } + _PSM_WRITE_PARAM(PSM_WANMANAGER_IF_ENABLE); + + _ansc_sprintf(param_value, "%d", p_Interface->Wan.Type ); + _PSM_WRITE_PARAM(PSM_WANMANAGER_IF_TYPE); + + _ansc_sprintf(param_value, "%d", p_Interface->Wan.Priority ); + _PSM_WRITE_PARAM(PSM_WANMANAGER_IF_PRIORITY); + + _PSM_WRITE_PARAM(PSM_WANMANAGER_IF_SELECTIONTIMEOUT); + _ansc_sprintf(param_value, "%d", p_Interface->Wan.SelectionTimeout ); + + if(p_Interface->DynamicTrigger.Enable) { + _ansc_sprintf(param_value, "TRUE"); + } + else { + _ansc_sprintf(param_value, "FALSE"); + } + _PSM_WRITE_PARAM(PSM_WANMANAGER_IF_DYNTRIGGERENABLE); + + if(p_Interface->Wan.EnableMAPT) + { + _ansc_sprintf(param_value, "TRUE"); + } + else + { + _ansc_sprintf(param_value, "FALSE"); + } + _PSM_WRITE_PARAM(PSM_WANMANAGER_IF_WAN_ENABLE_MAPT); + + if(p_Interface->Wan.EnableDSLite) + { + _ansc_sprintf(param_value, "TRUE"); + } + else + { + _ansc_sprintf(param_value, "FALSE"); + } + _PSM_WRITE_PARAM(PSM_WANMANAGER_IF_WAN_ENABLE_DSLITE); + + if(p_Interface->Wan.EnableIPoE) + { + _ansc_sprintf(param_value, "TRUE"); + } + else + { + _ansc_sprintf(param_value, "FALSE"); + } + _PSM_WRITE_PARAM(PSM_WANMANAGER_IF_WAN_ENABLE_IPOE); + + if(p_Interface->Wan.Validation.DiscoverOffer) + { + _ansc_sprintf(param_value, "TRUE"); + } + else + { + _ansc_sprintf(param_value, "FALSE"); + } + + if(p_Interface->PPP.Enable) + { + _ansc_sprintf(param_value, "TRUE"); + } + else + { + _ansc_sprintf(param_value, "FALSE"); + } + _PSM_WRITE_PARAM(PSM_WANMANAGER_IF_WAN_PPP_ENABLE); + + if(p_Interface->PPP.LinkType == WAN_IFACE_PPP_LINK_TYPE_PPPoA) + { + _ansc_sprintf(param_value, "PPPoA"); + } + else if(p_Interface->PPP.LinkType == WAN_IFACE_PPP_LINK_TYPE_PPPoE) + { + _ansc_sprintf(param_value, "PPPoE"); + } + _PSM_WRITE_PARAM(PSM_WANMANAGER_IF_WAN_PPP_LINKTYPE); + + if(p_Interface->PPP.IPCPEnable) + { + _ansc_sprintf(param_value, "TRUE"); + } + else + { + _ansc_sprintf(param_value, "FALSE"); + } + _PSM_WRITE_PARAM(PSM_WANMANAGER_IF_WAN_PPP_IPCP_ENABLE); + + if(p_Interface->PPP.IPV6CPEnable) + { + _ansc_sprintf(param_value, "TRUE"); + } + else + { + _ansc_sprintf(param_value, "FALSE"); + } + _PSM_WRITE_PARAM(PSM_WANMANAGER_IF_WAN_PPP_IPV6CP_ENABLE); + + _ansc_sprintf(param_value, "%d", p_Interface->Wan.Priority ); + _PSM_WRITE_PARAM(PSM_WANMANAGER_IF_PRIORITY); + + _PSM_WRITE_PARAM(PSM_WANMANAGER_IF_DYNTRIGGERDELAY); + _ansc_sprintf(param_value, "%d", p_Interface->DynamicTrigger.Delay ); + + return ANSC_STATUS_SUCCESS; +} + +static int write_Wan_Interface_Validation_ParametersToPSM(ULONG instancenum, DML_WAN_IFACE* p_Interface) +{ + if (NULL == p_Interface) + { + AnscTraceFlow(("%s Invalid memory!!!\n", __FUNCTION__)); + return ANSC_STATUS_INTERNAL_ERROR; + } + + int retPsmSet = CCSP_SUCCESS; + char param_name[256] = {0}; + char param_value[256] = {0}; + + memset(param_value, 0, sizeof(param_value)); + memset(param_name, 0, sizeof(param_name)); + + if(p_Interface->Wan.Validation.DiscoverOffer) + { + _ansc_sprintf(param_value, "TRUE"); + } + else + { + _ansc_sprintf(param_value, "FALSE"); + } + _PSM_WRITE_PARAM(PSM_WANMANAGER_IF_WAN_VALIDATION_DISCOVERY_OFFER); + + if(p_Interface->Wan.Validation.SolicitAdvertise) + { + _ansc_sprintf(param_value, "TRUE"); + } + else + { + _ansc_sprintf(param_value, "FALSE"); + } + _PSM_WRITE_PARAM(PSM_WANMANAGER_IF_WAN_VALIDATION_SOLICIT_ADVERTISE); + + if(p_Interface->Wan.Validation.RS_RA) + { + _ansc_sprintf(param_value, "TRUE"); + } + else + { + _ansc_sprintf(param_value, "FALSE"); + } + _PSM_WRITE_PARAM(PSM_WANMANAGER_IF_WAN_VALIDATION_RS_RA); + + if(p_Interface->Wan.Validation.PadiPado) + { + _ansc_sprintf(param_value, "TRUE"); + } + else + { + _ansc_sprintf(param_value, "FALSE"); + } + _PSM_WRITE_PARAM(PSM_WANMANAGER_IF_WAN_VALIDATION_PADI_PADO); + + return ANSC_STATUS_SUCCESS; +} + + + +/* DmlWanGetPSMRecordValue() */ +static int +DmlWanGetPSMRecordValue + ( + char *pPSMEntry, + char *pOutputString + ) +{ + int retPsmGet = CCSP_SUCCESS; + char *strValue = NULL; + + //Validate buffer + if( ( NULL == pPSMEntry ) && ( NULL == pOutputString ) ) + { + CcspTraceError(("%s %d Invalid buffer\n",__FUNCTION__,__LINE__)); + return retPsmGet; + } + + retPsmGet = PSM_Get_Record_Value2( bus_handle, g_Subsystem, pPSMEntry, NULL, &strValue ); + if ( retPsmGet == CCSP_SUCCESS ) + { + //Copy till end of the string + snprintf( pOutputString, strlen( strValue ) + 1, "%s", strValue ); + + ((CCSP_MESSAGE_BUS_INFO *)bus_handle)->freefunc(strValue); + } + + return retPsmGet; +} + +/* DmlWanSetPSMRecordValue() */ +static int +DmlWanSetPSMRecordValue + ( + char *pPSMEntry, + char *pSetString + ) +{ + int retPsmGet = CCSP_SUCCESS; + + //Validate buffer + if( ( NULL == pPSMEntry ) && ( NULL == pSetString ) ) + { + CcspTraceError(("%s %d Invalid buffer\n",__FUNCTION__,__LINE__)); + return retPsmGet; + } + + retPsmGet = PSM_Set_Record_Value2( bus_handle, g_Subsystem, pPSMEntry, ccsp_string, pSetString ); + + return retPsmGet; +} + +/* DmlWanDeletePSMRecordValue() */ +static int +DmlWanDeletePSMRecordValue + ( + char *pPSMEntry + ) +{ + int retPsmGet = CCSP_SUCCESS; + + //Validate buffer + if( NULL == pPSMEntry ) + { + CcspTraceError(("%s %d Invalid buffer\n",__FUNCTION__,__LINE__)); + return retPsmGet; + } + + retPsmGet = PSM_Del_Record( bus_handle, g_Subsystem, pPSMEntry ); + + return retPsmGet; +} + + +#ifdef FEATURE_802_1P_COS_MARKING + +#ifdef _HUB4_PRODUCT_REQ_ +static void AddSkbMarkingToConfFile(UINT data_skb_mark) +{ + FILE * fp = fopen(DATA_SKB_MARKING_LOCATION, "w+"); + if (!fp) + { + AnscTraceError(("%s Error writing skb mark\n", __FUNCTION__)); + } + else + { + fprintf(fp, "data_skb_marking %d\n",data_skb_mark); + fclose(fp); + } +} +#endif + +/* DmlWanIfMarkingInit() */ +static ANSC_STATUS WanMgr_WanIfaceMarkingInit (WanMgr_IfaceCtrl_Data_t* pWanIfaceCtrl) +{ + INT iLoopCount = 0; + + //Validate received buffer + if( NULL == pWanIfaceCtrl ) + { + CcspTraceError(("%s %d - Invalid buffer\n", __FUNCTION__, __LINE__)); + return ANSC_STATUS_FAILURE; + } + + //Initialise Marking Params + for( iLoopCount = 0; iLoopCount < pWanIfaceCtrl->ulTotalNumbWanInterfaces; iLoopCount++ ) + { + WanMgr_Iface_Data_t* pWanIfaceData = WanMgr_GetIfaceData_locked(iLoopCount); + if(pWanIfaceData != NULL) + { + DML_WAN_IFACE* pWanIface = &(pWanIfaceData->data); + DATAMODEL_MARKING* pDataModelMarking = &(pWanIface->Marking); + ULONG ulIfInstanceNumber = 0; + char acPSMQuery[128] = { 0 }, + acPSMValue[64] = { 0 }; + + /* Initiation all params */ + AnscSListInitializeHeader( &pDataModelMarking->MarkingList ); + pDataModelMarking->ulNextInstanceNumber = 1; + + //Interface instance number + ulIfInstanceNumber = pWanIface->uiInstanceNumber; + + //Query marking list for corresponding interface + snprintf( acPSMQuery, sizeof( acPSMQuery ), PSM_MARKING_LIST, ulIfInstanceNumber ); + if ( ( CCSP_SUCCESS == DmlWanGetPSMRecordValue( acPSMQuery, acPSMValue ) ) && \ + ( strlen( acPSMValue ) > 0 ) ) + { + char acTmpString[64] = { 0 }; + char *token = NULL; + + + //Parse PSM output + snprintf( acTmpString, sizeof( acTmpString ), acPSMValue ); + + //split marking table value + token = strtok( acTmpString, "-" ); + + //check and add + while ( token != NULL ) + { + CONTEXT_MARKING_LINK_OBJECT* pMarkingCxtLink = NULL; + ULONG ulInstanceNumber = 0; + + /* Insert into marking table */ + if( ( NULL != ( pMarkingCxtLink = WanManager_AddIfaceMarking( pWanIface, &ulInstanceNumber ) ) ) && + ( 0 < ulInstanceNumber ) ) + { + DML_MARKING* p_Marking = ( DML_MARKING* )pMarkingCxtLink->hContext; + + //Reset this flag during init so set should happen in next time onwards + pMarkingCxtLink->bNew = FALSE; + + if( NULL != p_Marking ) + { + char acTmpMarkingData[ 32 ] = { 0 }; + + //Stores into tmp buffer + snprintf( acTmpMarkingData, sizeof( acTmpMarkingData ), "%s", token ); + + //Get Alias from PSM + memset( acPSMQuery, 0, sizeof( acPSMQuery ) ); + memset( acPSMValue, 0, sizeof( acPSMValue ) ); + + snprintf( acPSMQuery, sizeof( acPSMQuery ), PSM_MARKING_ALIAS, ulIfInstanceNumber, acTmpMarkingData ); + if ( ( CCSP_SUCCESS == DmlWanGetPSMRecordValue( acPSMQuery, acPSMValue ) ) && \ + ( strlen( acPSMValue ) > 0 ) ) + { + snprintf( p_Marking->Alias, sizeof( p_Marking->Alias ), "%s", acPSMValue ); + } + + //Get SKB Port from PSM + memset( acPSMQuery, 0, sizeof( acPSMQuery ) ); + memset( acPSMValue, 0, sizeof( acPSMValue ) ); + + snprintf( acPSMQuery, sizeof( acPSMQuery ), PSM_MARKING_SKBPORT, ulIfInstanceNumber, acTmpMarkingData ); + if ( ( CCSP_SUCCESS == DmlWanGetPSMRecordValue( acPSMQuery, acPSMValue ) ) && \ + ( strlen( acPSMValue ) > 0 ) ) + { + p_Marking->SKBPort = atoi( acPSMValue ); + + //Re-adjust SKB Port if it is not matching with instance number + if ( p_Marking->InstanceNumber != p_Marking->SKBPort ) + { + p_Marking->SKBPort = p_Marking->InstanceNumber; + + //Set SKB Port into PSM + memset( acPSMValue, 0, sizeof( acPSMValue ) ); + + snprintf( acPSMValue, sizeof( acPSMValue ), "%u", p_Marking->SKBPort ); + DmlWanSetPSMRecordValue( acPSMQuery, acPSMValue ); + } + } + + //Get SKB Mark from PSM + memset( acPSMQuery, 0, sizeof( acPSMQuery ) ); + memset( acPSMValue, 0, sizeof( acPSMValue ) ); + + snprintf( acPSMQuery, sizeof( acPSMQuery ), PSM_MARKING_SKBMARK, ulIfInstanceNumber, acTmpMarkingData ); + if ( ( CCSP_SUCCESS == DmlWanGetPSMRecordValue( acPSMQuery, acPSMValue ) ) && \ + ( strlen( acPSMValue ) > 0 ) ) + { + /* + * Re-adjust SKB Mark + * + * 0x100000 * InstanceNumber(1,2,3, etc) + * 1048576 is decimal equalent to 0x100000 hexa decimal + */ + p_Marking->SKBMark = ( p_Marking->InstanceNumber ) * ( 1048576 ); + + //Set SKB Port into PSM + memset( acPSMValue, 0, sizeof( acPSMValue ) ); + + snprintf( acPSMValue, sizeof( acPSMValue ), "%u", p_Marking->SKBMark ); + DmlWanSetPSMRecordValue( acPSMQuery, acPSMValue ); + } + + //Get Ethernet Priority Mark from PSM + memset( acPSMQuery, 0, sizeof( acPSMQuery ) ); + memset( acPSMValue, 0, sizeof( acPSMValue ) ); + + snprintf( acPSMQuery, sizeof( acPSMQuery ), PSM_MARKING_ETH_PRIORITY_MASK, ulIfInstanceNumber, acTmpMarkingData ); + if ( ( CCSP_SUCCESS == DmlWanGetPSMRecordValue( acPSMQuery, acPSMValue ) ) && \ + ( strlen( acPSMValue ) > 0 ) ) + { + p_Marking->EthernetPriorityMark = atoi( acPSMValue ); + } + + CcspTraceInfo(("%s - Name[%s] Data[%s,%u,%u,%d]\n", __FUNCTION__, acTmpMarkingData, p_Marking->Alias, p_Marking->SKBPort, p_Marking->SKBMark, p_Marking->EthernetPriorityMark)); + + +#ifdef _HUB4_PRODUCT_REQ_ + /* Adding skb mark to config file if alis is 'DATA', so that udhcpc could use it to mark dhcp packets */ + if(0 == strncmp(p_Marking->Alias, "DATA", 4)) + { + AddSkbMarkingToConfFile(p_Marking->SKBMark); + } +#endif + } + } + + token = strtok( NULL, "-" ); + } + } + + WanMgrDml_GetIfaceData_release(pWanIfaceData); + } + } + + return ANSC_STATUS_SUCCESS; +} + +/* * SListPushMarkingEntryByInsNum() */ +ANSC_STATUS +SListPushMarkingEntryByInsNum + ( + PSLIST_HEADER pListHead, + PCONTEXT_LINK_OBJECT pLinkContext + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PCONTEXT_LINK_OBJECT pLineContextEntry = (PCONTEXT_LINK_OBJECT)NULL; + PSINGLE_LINK_ENTRY pSLinkEntry = (PSINGLE_LINK_ENTRY )NULL; + ULONG ulIndex = 0; + + if ( pListHead->Depth == 0 ) + { + AnscSListPushEntryAtBack(pListHead, &pLinkContext->Linkage); + } + else + { + pSLinkEntry = AnscSListGetFirstEntry(pListHead); + + for ( ulIndex = 0; ulIndex < pListHead->Depth; ulIndex++ ) + { + pLineContextEntry = ACCESS_CONTEXT_LINK_OBJECT(pSLinkEntry); + pSLinkEntry = AnscSListGetNextEntry(pSLinkEntry); + + if ( pLinkContext->InstanceNumber < pLineContextEntry->InstanceNumber ) + { + AnscSListPushEntryByIndex(pListHead, &pLinkContext->Linkage, ulIndex); + + return ANSC_STATUS_SUCCESS; + } + } + + AnscSListPushEntryAtBack(pListHead, &pLinkContext->Linkage); + } + + return ANSC_STATUS_SUCCESS; +} + +PCONTEXT_LINK_OBJECT SListGetEntryByInsNum( PSLIST_HEADER pListHead, ULONG InstanceNumber) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PCONTEXT_LINK_OBJECT pContextEntry = (PCONTEXT_LINK_OBJECT)NULL; + PSINGLE_LINK_ENTRY pSLinkEntry = (PSINGLE_LINK_ENTRY )NULL; + ULONG ulIndex = 0; + + if ( pListHead->Depth == 0 ) + { + return NULL; + } + else + { + pSLinkEntry = AnscSListGetFirstEntry(pListHead); + + for ( ulIndex = 0; ulIndex < pListHead->Depth; ulIndex++ ) + { + pContextEntry = ACCESS_CONTEXT_LINK_OBJECT(pSLinkEntry); + pSLinkEntry = AnscSListGetNextEntry(pSLinkEntry); + + if ( pContextEntry->InstanceNumber == InstanceNumber ) + { + return pContextEntry; + } + } + } + + return NULL; +} + + +ANSC_STATUS +DmlCheckAndProceedMarkingOperations + ( + ANSC_HANDLE hContext, + DML_MARKING* pMarking, + DML_WAN_MARKING_DML_OPERATIONS enMarkingOp + ) +{ + char acPSMQuery[128] = { 0 }, + acPSMValue[64] = { 0 }; + ULONG ulIfInstanceNumber = 0; + + //Validate param + if ( NULL == pMarking ) + { + CcspTraceError(("%s %d Invalid Buffer\n", __FUNCTION__,__LINE__)); + return ANSC_STATUS_FAILURE; + } + + //Find the Marking entry in PSM + ulIfInstanceNumber = pMarking->ulWANIfInstanceNumber; + + //Query marking list for corresponding interface + snprintf( acPSMQuery, sizeof( acPSMQuery ), PSM_MARKING_LIST, ulIfInstanceNumber ); + if ( CCSP_SUCCESS == DmlWanGetPSMRecordValue( acPSMQuery, acPSMValue ) ) + { + char acTmpString[64] = { 0 }, + acFoundMarkingRecord[64] = { 0 }; + char *token = NULL; + BOOL IsMarkingRecordFound = FALSE; + + //Parse PSM output + snprintf( acTmpString, sizeof( acTmpString ), acPSMValue ); + + //split marking table value + token = strtok( acTmpString, "-" ); + + //check and add + while ( token != NULL ) + { + if( 0 == strcmp( pMarking->Alias, token ) ) + { + IsMarkingRecordFound = TRUE; + snprintf( acFoundMarkingRecord, sizeof( acFoundMarkingRecord ), "%s", token ); + break; + } + + token = strtok( NULL, "-" ); + } + + /* + * + * Note: + * ---- + * If record found when add then reject that process + * If record not found when add then needs to create new entry and update fields and LIST + * + * If record not found when delete then reject that process + * If record found when delete then needs to delete all corresponding fields in DB and update LIST + * + * If record not found when update then reject that process + * If record found when update then needs to update fields only not LIST + * + */ + switch( enMarkingOp ) + { + case WAN_MARKING_ADD: + { + char acPSMRecEntry[64], + acPSMRecValue[64]; + + if( TRUE == IsMarkingRecordFound ) + { + CcspTraceError(("%s %d - Failed to add since record(%s) already exists!\n",__FUNCTION__,__LINE__,acFoundMarkingRecord)); + return ANSC_STATUS_FAILURE; + } + + //Set LIST into PSM + memset( acPSMRecEntry, 0, sizeof( acPSMRecEntry ) ); + memset( acPSMRecValue, 0, sizeof( acPSMRecValue ) ); + + snprintf( acPSMRecEntry, sizeof( acPSMRecEntry ), PSM_MARKING_LIST, ulIfInstanceNumber ); + + //Check whether already LIST is having another MARKING or not. + if( 0 < strlen( acPSMValue ) ) + { + snprintf( acPSMRecValue, sizeof( acPSMRecValue ), "%s-%s", acPSMValue, pMarking->Alias ); + } + else + { + snprintf( acPSMRecValue, sizeof( acPSMRecValue ), "%s", pMarking->Alias ); + } + + //Check set is proper or not + if ( CCSP_SUCCESS != DmlWanSetPSMRecordValue( acPSMRecEntry, acPSMRecValue ) ) + { + CcspTraceError(("%s %d Failed to set PSM record %s\n", __FUNCTION__,__LINE__,acPSMRecEntry)); + return ANSC_STATUS_FAILURE; + } + + //Set Alias into PSM + memset( acPSMRecEntry, 0, sizeof( acPSMRecEntry ) ); + memset( acPSMRecValue, 0, sizeof( acPSMRecValue ) ); + + snprintf( acPSMRecEntry, sizeof( acPSMRecEntry ), PSM_MARKING_ALIAS, ulIfInstanceNumber, pMarking->Alias ); + snprintf( acPSMRecValue, sizeof( acPSMRecValue ), "%s", pMarking->Alias ); + DmlWanSetPSMRecordValue( acPSMRecEntry, acPSMRecValue ); + + //Set SKBPort into PSM + memset( acPSMRecEntry, 0, sizeof( acPSMRecEntry ) ); + memset( acPSMRecValue, 0, sizeof( acPSMRecValue ) ); + + snprintf( acPSMRecEntry, sizeof( acPSMRecEntry ), PSM_MARKING_SKBPORT, ulIfInstanceNumber, pMarking->Alias ); + + /* + * Generate SKB port + * + * Stores the SKB Port for the entry. This is auto-generated for each entry starting from "1". + * Its value matches the instance index. + */ + pMarking->SKBPort = pMarking->InstanceNumber; + + snprintf( acPSMRecValue, sizeof( acPSMRecValue ), "%u", pMarking->SKBPort ); + DmlWanSetPSMRecordValue( acPSMRecEntry, acPSMRecValue ); + + //Set SKBMark into PSM + memset( acPSMRecEntry, 0, sizeof( acPSMRecEntry ) ); + memset( acPSMRecValue, 0, sizeof( acPSMRecValue ) ); + + snprintf( acPSMRecEntry, sizeof( acPSMRecEntry ), PSM_MARKING_SKBMARK, ulIfInstanceNumber, pMarking->Alias ); + + /* + * Generate SKB Mark + * + * Stores the SKB Mark for the entry. This is auto-generated for each entry starting from "0x100000". + * Its value increments by "0x100000", so the next would be "0x200000", then "0x300000", etc... + * + * 0x100000 * InstanceNumber(1,2,3, etc) + * 1048576 is decimal equalent to 0x100000 hexa decimal + */ + pMarking->SKBMark = ( pMarking->InstanceNumber ) * ( 1048576 ); + snprintf( acPSMRecValue, sizeof( acPSMRecValue ), "%u", pMarking->SKBMark ); + DmlWanSetPSMRecordValue( acPSMRecEntry, acPSMRecValue ); + + //Set Ethernet Priority Mark into PSM + memset( acPSMRecEntry, 0, sizeof( acPSMRecEntry ) ); + memset( acPSMRecValue, 0, sizeof( acPSMRecValue ) ); + + snprintf( acPSMRecEntry, sizeof( acPSMRecEntry ), PSM_MARKING_ETH_PRIORITY_MASK, ulIfInstanceNumber, pMarking->Alias ); + snprintf( acPSMRecValue, sizeof( acPSMRecValue ), "%d", pMarking->EthernetPriorityMark ); + DmlWanSetPSMRecordValue( acPSMRecEntry, acPSMRecValue ); + + CcspTraceInfo(("%s Marking table(%s) and records added successfully\n",__FUNCTION__,pMarking->Alias)); + } + break; /* * WAN_MARKING_ADD */ + + case WAN_MARKING_UPDATE: + { + char acPSMRecEntry[64], + acPSMRecValue[64]; + + if( FALSE == IsMarkingRecordFound ) + { + CcspTraceError(("%s %d - Failed to update since record(%s) not exists!\n",__FUNCTION__,__LINE__,pMarking->Alias)); + return ANSC_STATUS_FAILURE; + } + + //Set Alias into PSM + memset( acPSMRecEntry, 0, sizeof( acPSMRecEntry ) ); + memset( acPSMRecValue, 0, sizeof( acPSMRecValue ) ); + + snprintf( acPSMRecEntry, sizeof( acPSMRecEntry ), PSM_MARKING_ALIAS, ulIfInstanceNumber, pMarking->Alias ); + snprintf( acPSMRecValue, sizeof( acPSMRecValue ), "%s", pMarking->Alias ); + DmlWanSetPSMRecordValue( acPSMRecEntry, acPSMRecValue ); + + //Set SKBPort into PSM + memset( acPSMRecEntry, 0, sizeof( acPSMRecEntry ) ); + memset( acPSMRecValue, 0, sizeof( acPSMRecValue ) ); + + snprintf( acPSMRecEntry, sizeof( acPSMRecEntry ), PSM_MARKING_SKBPORT, ulIfInstanceNumber, pMarking->Alias ); + snprintf( acPSMRecValue, sizeof( acPSMRecValue ), "%u", pMarking->SKBPort ); + DmlWanSetPSMRecordValue( acPSMRecEntry, acPSMRecValue ); + + //Set SKBMark into PSM + memset( acPSMRecEntry, 0, sizeof( acPSMRecEntry ) ); + memset( acPSMRecValue, 0, sizeof( acPSMRecValue ) ); + + snprintf( acPSMRecEntry, sizeof( acPSMRecEntry ), PSM_MARKING_SKBMARK, ulIfInstanceNumber, pMarking->Alias ); + snprintf( acPSMRecValue, sizeof( acPSMRecValue ), "%u", pMarking->SKBMark ); + DmlWanSetPSMRecordValue( acPSMRecEntry, acPSMRecValue ); + + //Set Ethernet Priority Mark into PSM + memset( acPSMRecEntry, 0, sizeof( acPSMRecEntry ) ); + memset( acPSMRecValue, 0, sizeof( acPSMRecValue ) ); + + snprintf( acPSMRecEntry, sizeof( acPSMRecEntry ), PSM_MARKING_ETH_PRIORITY_MASK, ulIfInstanceNumber, pMarking->Alias ); + snprintf( acPSMRecValue, sizeof( acPSMRecValue ), "%d", pMarking->EthernetPriorityMark ); + DmlWanSetPSMRecordValue( acPSMRecEntry, acPSMRecValue ); + + CcspTraceInfo(("%s Marking table(%s) and records updated successfully\n",__FUNCTION__,pMarking->Alias)); + } + break; /* * WAN_MARKING_UPDATE */ + + case WAN_MARKING_DELETE: + { + char acPSMRecEntry[64], + acPSMRecValue[64], + acNewMarkingList[64] = { 0 }, + acNewTmpString[64] = { 0 }, + *tmpToken = NULL; + INT iTotalMarking = 0; + + + if( FALSE == IsMarkingRecordFound ) + { + CcspTraceError(("%s %d - Failed to delete since record(%s) not exists!\n",__FUNCTION__,__LINE__,pMarking->Alias)); + return ANSC_STATUS_FAILURE; + } + + //Set Alias into PSM + memset( acPSMRecEntry, 0, sizeof( acPSMRecEntry ) ); + + snprintf( acPSMRecEntry, sizeof( acPSMRecEntry ), PSM_MARKING_ALIAS, ulIfInstanceNumber, pMarking->Alias ); + DmlWanDeletePSMRecordValue( acPSMRecEntry ); + + //Set SKBPort into PSM + memset( acPSMRecEntry, 0, sizeof( acPSMRecEntry ) ); + + snprintf( acPSMRecEntry, sizeof( acPSMRecEntry ), PSM_MARKING_SKBPORT, ulIfInstanceNumber, pMarking->Alias ); + DmlWanDeletePSMRecordValue( acPSMRecEntry ); + + //Set SKBMark into PSM + memset( acPSMRecEntry, 0, sizeof( acPSMRecEntry ) ); + + snprintf( acPSMRecEntry, sizeof( acPSMRecEntry ), PSM_MARKING_SKBMARK, ulIfInstanceNumber, pMarking->Alias ); + DmlWanDeletePSMRecordValue( acPSMRecEntry ); + + //Set Ethernet Priority Mark into PSM + memset( acPSMRecEntry, 0, sizeof( acPSMRecEntry ) ); + + snprintf( acPSMRecEntry, sizeof( acPSMRecEntry ), PSM_MARKING_ETH_PRIORITY_MASK, ulIfInstanceNumber, pMarking->Alias ); + DmlWanDeletePSMRecordValue( acPSMRecEntry ); + + //Remove entry from LIST + + //Parse PSM output + snprintf( acNewTmpString, sizeof( acNewTmpString ), acPSMValue ); + + //split marking table value + tmpToken = strtok( acNewTmpString, "-" ); + + //check and add + while ( tmpToken != NULL ) + { + //Copy all the values except delete alias + if( 0 != strcmp( pMarking->Alias, tmpToken ) ) + { + if( 0 == iTotalMarking ) + { + snprintf( acNewMarkingList, sizeof( acNewMarkingList ), "%s", tmpToken ); + } + else + { + //Append remaining marking strings + strncat( acNewMarkingList, "-", strlen("-") + 1 ); + strncat( acNewMarkingList, tmpToken, strlen( tmpToken ) + 1 ); + } + + iTotalMarking++; + } + + tmpToken = strtok( NULL, "-" ); + } + + //Check whether any marking available or not + if( iTotalMarking == 0 ) + { + snprintf( acPSMRecValue, sizeof( acPSMRecValue ), "%s", "" ); //Copy empty + } + else + { + snprintf( acPSMRecValue, sizeof( acPSMRecValue ), "%s", acNewMarkingList ); //Copy new string + } + + //Set Marking LIST into PSM + memset( acPSMRecEntry, 0, sizeof( acPSMRecEntry ) ); + + snprintf( acPSMRecEntry, sizeof( acPSMRecEntry ), PSM_MARKING_LIST, ulIfInstanceNumber ); + + DmlWanSetPSMRecordValue( acPSMRecEntry, acPSMRecValue ); + + CcspTraceInfo(("%s Marking table(%s) and records deleted successfully\n",__FUNCTION__,pMarking->Alias)); + } + break; /* * WAN_MARKING_DELETE */ + + default: + { + CcspTraceError(("%s Invalid case\n",__FUNCTION__)); + return ANSC_STATUS_FAILURE; + } + } + } + + return ANSC_STATUS_SUCCESS; +} + +/* * DmlAddMarking() */ +ANSC_STATUS +DmlAddMarking + ( + ANSC_HANDLE hContext, + DML_MARKING* pMarking + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + + //Validate param + if ( NULL == pMarking ) + { + CcspTraceError(("%s %d Invalid Buffer\n", __FUNCTION__,__LINE__)); + return ANSC_STATUS_FAILURE; + } + + returnStatus = DmlCheckAndProceedMarkingOperations( hContext, pMarking, WAN_MARKING_ADD ); + + if( ANSC_STATUS_SUCCESS != returnStatus ) + { + CcspTraceError(("%s %d - Failed to Add Marking Entry\n",__FUNCTION__,__LINE__)); + } + + return ANSC_STATUS_SUCCESS; +} + +/* * DmlDeleteMarking() */ +ANSC_STATUS +DmlDeleteMarking + ( + ANSC_HANDLE hContext, + DML_MARKING* pMarking + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + + //Validate param + if ( NULL == pMarking ) + { + CcspTraceError(("%s %d Invalid Buffer\n", __FUNCTION__,__LINE__)); + return ANSC_STATUS_FAILURE; + } + + returnStatus = DmlCheckAndProceedMarkingOperations( hContext, pMarking, WAN_MARKING_DELETE ); + + if( ANSC_STATUS_SUCCESS != returnStatus ) + { + CcspTraceError(("%s %d - Failed to Delete Marking Entry\n",__FUNCTION__,__LINE__)); + } + + return returnStatus; +} + +/* * DmlSetMarking() */ +ANSC_STATUS +DmlSetMarking + ( + ANSC_HANDLE hContext, + DML_MARKING* pMarking + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + + //Validate param + if ( NULL == pMarking ) + { + CcspTraceError(("%s %d Invalid Buffer\n", __FUNCTION__,__LINE__)); + return ANSC_STATUS_FAILURE; + } + + returnStatus = DmlCheckAndProceedMarkingOperations( hContext, pMarking, WAN_MARKING_UPDATE ); + + if( ANSC_STATUS_SUCCESS != returnStatus ) + { + CcspTraceError(("%s %d - Failed to Update Marking Entry\n",__FUNCTION__,__LINE__)); + } + + return returnStatus; +} +#endif /* * FEATURE_802_1P_COS_MARKING */ + +/* DmlGetTotalNoOfWanInterfaces() */ +ANSC_STATUS DmlGetTotalNoOfWanInterfaces(int *wan_if_count) +{ + int ret_val = ANSC_STATUS_SUCCESS; + int retPsmGet = CCSP_SUCCESS; + char* param_value = NULL; + + retPsmGet = PSM_Get_Record_Value2(bus_handle,g_Subsystem, PSM_WANMANAGER_WANIFCOUNT, NULL, ¶m_value); + if (retPsmGet != CCSP_SUCCESS) { \ + AnscTraceFlow(("%s Error %d reading %s %s\n", __FUNCTION__, retPsmGet, PSM_WANMANAGER_WANIFCOUNT, param_value)); + ret_val = ANSC_STATUS_FAILURE; + } + else if(param_value != NULL) { + _ansc_sscanf(param_value, "%d", wan_if_count); + ((CCSP_MESSAGE_BUS_INFO *)bus_handle)->freefunc(param_value); + } + + return ret_val; +} + +/* DmlGetWanIfCfg() */ +ANSC_STATUS DmlGetWanIfCfg( INT LineIndex, DML_WAN_IFACE* pstLineInfo ) +{ + return ANSC_STATUS_SUCCESS; +} + + +/* DmlSetWanIfCfg() */ +ANSC_STATUS DmlSetWanIfCfg( INT LineIndex, DML_WAN_IFACE* pstLineInfo ) +{ + int ret_val = ANSC_STATUS_SUCCESS; + ret_val = write_Wan_Interface_ParametersFromPSM(LineIndex, pstLineInfo); + if(ret_val != ANSC_STATUS_SUCCESS) { + AnscTraceFlow(("%s Failed!! Error code: %d", __FUNCTION__, ret_val)); + } + + return ret_val; +} + +/* DmlSetWanIfValidationCfg() */ +ANSC_STATUS DmlSetWanIfValidationCfg( INT WanIfIndex, DML_WAN_IFACE* pWanIfInfo) +{ + int ret_val = ANSC_STATUS_SUCCESS; + + if (NULL == pWanIfInfo) + { + AnscTraceFlow(("%s Failed!! Invalid memory \n", __FUNCTION__)); + return ANSC_STATUS_INTERNAL_ERROR; + } + ret_val = write_Wan_Interface_Validation_ParametersToPSM(WanIfIndex, pWanIfInfo); + if(ret_val != ANSC_STATUS_SUCCESS) { + AnscTraceFlow(("%s Failed!! Error code: %d", __FUNCTION__, ret_val)); + } + + return ret_val; +} + +static ANSC_STATUS WanMgr_WanIfaceConfInit(WanMgr_IfaceCtrl_Data_t* pWanIfaceCtrl) +{ + if(pWanIfaceCtrl != NULL) + { + ANSC_STATUS result; + UINT uiTotalIfaces; + UINT idx; + + result = DmlGetTotalNoOfWanInterfaces(&uiTotalIfaces); + if(result == ANSC_STATUS_FAILURE) { + return ANSC_STATUS_FAILURE; + } + + pWanIfaceCtrl->pIface = (WanMgr_Iface_Data_t*) AnscAllocateMemory( sizeof(WanMgr_Iface_Data_t) * uiTotalIfaces); + if( NULL == pWanIfaceCtrl->pIface ) + { + return ANSC_STATUS_FAILURE; + } + + pWanIfaceCtrl->ulTotalNumbWanInterfaces = uiTotalIfaces; + + //Memset all memory + memset( pWanIfaceCtrl->pIface, 0, ( sizeof(WanMgr_Iface_Data_t) * uiTotalIfaces ) ); + + //Get static interface configuration from PSM data store + for( idx = 0 ; idx < uiTotalIfaces ; idx++ ) + { + WanMgr_Iface_Data_t* pIfaceData = &(pWanIfaceCtrl->pIface[idx]); + WanMgr_IfaceData_Init(pIfaceData, idx); + get_Wan_Interface_ParametersFromPSM((idx+1), &(pIfaceData->data)); + } + } + + return ANSC_STATUS_SUCCESS; +} + + +static ANSC_STATUS WanMgr_WanConfInit (DML_WANMGR_CONFIG* pWanConfig) +{ + unsigned int wan_enable; + unsigned int wan_policy; + unsigned int wan_idle_timeout; + int ret_val = ANSC_STATUS_SUCCESS; + int retPsmGet = CCSP_SUCCESS; + char param_name[256] = {0}; + char* param_value = NULL; + + memset(param_name, 0, sizeof(param_name)); + _ansc_sprintf(param_name, PSM_WANMANAGER_WANENABLE); + retPsmGet = PSM_Get_Record_Value2(bus_handle, g_Subsystem, param_name, NULL, ¶m_value); + if (retPsmGet == CCSP_SUCCESS && param_value != NULL) + wan_enable = atoi(param_value); + else + ret_val = ANSC_STATUS_FAILURE; + + pWanConfig->Enable = wan_enable; + + memset(param_name, 0, sizeof(param_name)); + _ansc_sprintf(param_name, PSM_WANMANAGER_WANPOLICY); + retPsmGet = PSM_Get_Record_Value2(bus_handle, g_Subsystem, param_name, NULL, ¶m_value); + if (retPsmGet == CCSP_SUCCESS && param_value != NULL) + wan_policy = atoi(param_value); + else + ret_val = ANSC_STATUS_FAILURE; + + pWanConfig->Policy = wan_policy; + + memset(param_name, 0, sizeof(param_name)); + _ansc_sprintf(param_name, PSM_WANMANAGER_WANIDLETIMEOUT); + retPsmGet = PSM_Get_Record_Value2(bus_handle, g_Subsystem, param_name, NULL, ¶m_value); + if (retPsmGet == CCSP_SUCCESS && param_value != NULL) + wan_idle_timeout = atoi(param_value); + else + ret_val = ANSC_STATUS_FAILURE; + + pWanConfig->IdleTimeout = wan_idle_timeout; + + if(param_value != NULL) + ((CCSP_MESSAGE_BUS_INFO *)bus_handle)->freefunc(param_value); + + return ret_val; +} + + +ANSC_STATUS WanMgr_WanConfigInit(void) +{ + ANSC_STATUS retStatus = ANSC_STATUS_FAILURE; + + //Wan Configuration init + WanMgr_Config_Data_t* pWanConfigData = WanMgr_GetConfigData_locked(); + if(pWanConfigData != NULL) + { + retStatus = WanMgr_WanConfInit(&(pWanConfigData->data)); + + WanMgrDml_GetConfigData_release(pWanConfigData); + } + + if(retStatus != ANSC_STATUS_SUCCESS) + { + return retStatus; + } + + + //Wan Interface Configuration init + WanMgr_IfaceCtrl_Data_t* pWanIfaceCtrl = WanMgr_GetIfaceCtrl_locked(); + if(pWanIfaceCtrl != NULL) + { + retStatus = WanMgr_WanIfaceConfInit(pWanIfaceCtrl); + +#ifdef FEATURE_802_1P_COS_MARKING + /* Initialize middle layer for Device.X_RDK_WanManager.CPEInterface.{i}.Marking. */ + WanMgr_WanIfaceMarkingInit(pWanIfaceCtrl); +#endif /* * FEATURE_802_1P_COS_MARKING */ + + + WanMgrDml_GetIfaceCtrl_release(pWanIfaceCtrl); + } + + return retStatus; +} + + +ANSC_STATUS +SListPushEntryByInsNum + ( + PSLIST_HEADER pListHead, + PCONTEXT_LINK_OBJECT pContext + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PCONTEXT_LINK_OBJECT pContextEntry = (PCONTEXT_LINK_OBJECT)NULL; + PSINGLE_LINK_ENTRY pSLinkEntry = (PSINGLE_LINK_ENTRY )NULL; + ULONG ulIndex = 0; + + if ( pListHead->Depth == 0 ) + { + AnscSListPushEntryAtBack(pListHead, &pContext->Linkage); + } + else + { + pSLinkEntry = AnscSListGetFirstEntry(pListHead); + + for ( ulIndex = 0; ulIndex < pListHead->Depth; ulIndex++ ) + { + pContextEntry = ACCESS_CONTEXT_LINK_OBJECT(pSLinkEntry); + pSLinkEntry = AnscSListGetNextEntry(pSLinkEntry); + + if ( pContext->InstanceNumber < pContextEntry->InstanceNumber ) + { + AnscSListPushEntryByIndex(pListHead, &pContext->Linkage, ulIndex); + + return ANSC_STATUS_SUCCESS; + } + } + + AnscSListPushEntryAtBack(pListHead, &pContext->Linkage); + } + + return ANSC_STATUS_SUCCESS; +} diff --git a/source/TR-181/middle_layer_src/wanmgr_rdkbus_apis.h b/source/TR-181/middle_layer_src/wanmgr_rdkbus_apis.h new file mode 100644 index 00000000..e5c1135b --- /dev/null +++ b/source/TR-181/middle_layer_src/wanmgr_rdkbus_apis.h @@ -0,0 +1,54 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2019 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + + +#ifndef _WANMGR_RDKBUS_APIS_H_ +#define _WANMGR_RDKBUS_APIS_H_ + +#include "wanmgr_apis.h" +#include "ccsp_psm_helper.h" +#include "ansc_platform.h" +#include "ansc_string_util.h" +#include "wanmgr_dml.h" + +//PPP Manager +#define PPPMGR_COMPONENT_NAME "eRT.com.cisco.spvtg.ccsp.pppmanager" +#define PPPMGR_DBUS_PATH "/com/cisco/spvtg/ccsp/pppmanager" + +#define PPP_INTERFACE_TABLE "Device.PPP.Interface." +#define PPP_INTERFACE_ENABLE "Device.PPP.Interface.%d.Enable" +#define PPP_INTERFACE_ALIAS "Device.PPP.Interface.%d.Alias" +#define PPP_INTERFACE_LOWERLAYERS "Device.PPP.Interface.%d.LowerLayers" +#define PPP_INTERFACE_USERNAME "Device.PPP.Interface.%d.Username" +#define PPP_INTERFACE_PASSWORD "Device.PPP.Interface.%d.Password" +#define PPP_INTERFACE_IPCP_ENABLE "Device.PPP.Interface.%d.IPCPEnable" +#define PPP_INTERFACE_IPV6CP_ENABLE "Device.PPP.Interface.%d.IPv6CPEnable" +#define PPP_INTERFACE_LINKTYPE "Device.PPP.Interface.%d.X_RDK_LinkType" +#define PPP_IPCP_LOCAL_IPADDRESS "Device.PPP.Interface.%d.IPCP.LocalIPAddress" +#define PPP_IPCP_REMOTEIPADDRESS "Device.PPP.Interface.%d.IPCP.RemoteIPAddress" +#define PPP_IPCP_DNS_SERVERS "Device.PPP.Interface.%d.IPCP.DNSServers" +#define PPP_IPV6CP_REMOTE_IDENTIFIER "Device.PPP.Interface.%d.IPv6CP.RemoteInterfaceIdentifier" + +ANSC_STATUS WanMgr_WanConfigInit(void); +ANSC_STATUS DmlSetWanIfCfg( INT LineIndex, DML_WAN_IFACE* pstLineInfo ); +ANSC_STATUS DmlSetWanIfValidationCfg( INT WanIfIndex, DML_WAN_IFACE* pWanIfInfo); +ANSC_STATUS DmlAddMarking(ANSC_HANDLE hContext,DML_MARKING* pMarking); +ANSC_STATUS DmlDeleteMarking(ANSC_HANDLE hContext, DML_MARKING* pMarking); +ANSC_STATUS DmlSetMarking(ANSC_HANDLE hContext, DML_MARKING* pMarking); +#endif /* _WANMGR_RDKBUS_APIS_H_ */ diff --git a/source/TR-181/middle_layer_src/wanmgr_rdkbus_common.h b/source/TR-181/middle_layer_src/wanmgr_rdkbus_common.h new file mode 100644 index 00000000..04960fa6 --- /dev/null +++ b/source/TR-181/middle_layer_src/wanmgr_rdkbus_common.h @@ -0,0 +1,99 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2015 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +/********************************************************************** + Copyright [2014] [Cisco Systems, Inc.] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +**********************************************************************/ + +#ifndef _WANMGR_RDKBUS_COMMON_H_ +#define _WANMGR_RDKBUS_COMMON_H_ + +#include "ansc_platform.h" +#include "ansc_string_util.h" + +typedef ANSC_HANDLE (*PFN_DM_CREATE)(VOID); +typedef ANSC_STATUS (*PFN_DM_REMOVE)(ANSC_HANDLE hThisObject); +typedef ANSC_STATUS (*PFN_DM_INITIALIZE) (ANSC_HANDLE hThisObject); + +/* + * the main struct in cosa_xxx_apis.h need includes this struct and realize all functions. + */ +#define BASE_CONTENT \ + /* start of object class content */ \ + ULONG Oid; \ + ANSC_HANDLE hSbContext; \ + \ + PFN_DM_CREATE Create; \ + PFN_DM_REMOVE Remove; \ + PFN_DM_INITIALIZE Initialize; \ + +typedef struct _BASE_OBJECT +{ + BASE_CONTENT +} BASE_OBJECT, *PBASE_OBJECT; + +/* +* This struct is for creating entry context link in writable table when call GetEntry() +*/ +#define CONTEXT_LINK_CLASS_CONTENT \ + SINGLE_LINK_ENTRY Linkage; \ + ANSC_HANDLE hContext; \ + ANSC_HANDLE hParentTable; /* Back pointer */ \ + ULONG InstanceNumber; \ + BOOL bNew; \ + ANSC_HANDLE hPoamIrepUpperFo; \ + ANSC_HANDLE hPoamIrepFo; \ + +typedef struct _CONTEXT_LINK_OBJECT +{ + CONTEXT_LINK_CLASS_CONTENT +} CONTEXT_LINK_OBJECT, *PCONTEXT_LINK_OBJECT; + +#define ACCESS_CONTEXT_LINK_OBJECT(p) \ + ACCESS_CONTAINER(p, CONTEXT_LINK_OBJECT, Linkage) + +#define CONTEXT_LINK_INITIATION_CONTENT(cxt) \ + (cxt)->hContext = (ANSC_HANDLE)NULL; \ + (cxt)->hParentTable = (ANSC_HANDLE)NULL; \ + (cxt)->InstanceNumber = 0; \ + (cxt)->bNew = FALSE; \ + (cxt)->hPoamIrepUpperFo = (ANSC_HANDLE)NULL; \ + (cxt)->hPoamIrepFo = (ANSC_HANDLE)NULL; \ + +#define DML_ALIAS_NAME_LENGTH 64 +#define DML_DHCP_CLIENT_IFNAME "erouter0" +#define CFG_TR181_DHCPv6_SERVER_IfName "brlan0" + + +ANSC_STATUS SListPushEntryByInsNum (PSLIST_HEADER pListHead, PCONTEXT_LINK_OBJECT pLinkContext); +PCONTEXT_LINK_OBJECT SListGetEntryByInsNum (PSLIST_HEADER pListHead, ULONG InstanceNumber); + +#endif //_WANMGR_RDKBUS_COMMON_H_ diff --git a/source/TR-181/middle_layer_src/wanmgr_rdkbus_utils.c b/source/TR-181/middle_layer_src/wanmgr_rdkbus_utils.c new file mode 100644 index 00000000..ae7ecf9b --- /dev/null +++ b/source/TR-181/middle_layer_src/wanmgr_rdkbus_utils.c @@ -0,0 +1,484 @@ +/* + If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2020 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + + +/************************************************************************** + + module: wan_controller_utils.c + + For COSA Data Model Library Development + + ------------------------------------------------------------------- + + description: + + State machine to manage a Wan Controller + + ------------------------------------------------------------------- + + environment: + + Platform independent + + ------------------------------------------------------------------- + + author: + + COSA XML TOOL CODE GENERATOR 1.0 + + ------------------------------------------------------------------- + + revision: + + 13/02/2020 initial revision. + +**************************************************************************/ + +/* ---- Include Files ---------------------------------------- */ +#include "dmsb_tr181_psm_definitions.h" +#include "wanmgr_rdkbus_utils.h" +#include "ansc_platform.h" +#include "ccsp_psm_helper.h" +#include "wanmgr_data.h" +#include "wanmgr_data.h" + +extern char g_Subsystem[32]; +extern ANSC_HANDLE bus_handle; + +ANSC_STATUS WanMgr_RdkBus_getWanPolicy(DML_WAN_POLICY *wan_policy) +{ + int result = ANSC_STATUS_SUCCESS; + int retPsmGet = CCSP_SUCCESS; + char *param_value= NULL; + char param_name[BUFLEN_256]= {0}; + + memset(param_name, 0, sizeof(param_name)); + _ansc_sprintf(param_name, PSM_WANMANAGER_WANPOLICY); + retPsmGet = PSM_Get_Record_Value2(bus_handle, g_Subsystem, param_name, NULL, ¶m_value); + if (retPsmGet == CCSP_SUCCESS && param_value != NULL) { + *wan_policy = strtol(param_value, NULL, 10); + } + else { + result = ANSC_STATUS_FAILURE; + } + + if (retPsmGet == CCSP_SUCCESS) { + ((CCSP_MESSAGE_BUS_INFO *)bus_handle)->freefunc(param_value); + } + + return result; +} + + +ANSC_STATUS WanMgr_RdkBus_setWanPolicy(DML_WAN_POLICY wan_policy) +{ + int result = ANSC_STATUS_SUCCESS; + int retPsmSet = CCSP_SUCCESS; + char param_name[BUFLEN_256] = {0}; + char param_value[BUFLEN_256] = {0}; + + /* Update the wan policy information in PSM */ + memset(param_value, 0, sizeof(param_value)); + memset(param_name, 0, sizeof(param_name)); + + snprintf(param_value, sizeof(param_value), "%d", wan_policy); + _ansc_sprintf(param_name, PSM_WANMANAGER_WANPOLICY); + + retPsmSet = PSM_Set_Record_Value2(bus_handle,g_Subsystem, param_name, ccsp_string, param_value); + if (retPsmSet != CCSP_SUCCESS) { + AnscTraceError(("%s Error %d writing %s %s\n", __FUNCTION__, retPsmSet, param_name, param_value)); + result = ANSC_STATUS_FAILURE; + } + + return result; +} + + +ANSC_STATUS WanMgr_RdkBus_updateInterfaceUpstreamFlag(char *phyPath, BOOL flag) +{ + char param_name[BUFLEN_256] = {0}; + char param_value[BUFLEN_256] = {0}; + char pComponentName[BUFLEN_64] = {0}; + char pComponentPath[BUFLEN_64] = {0}; + char *faultParam = NULL; + int ret = 0; + + CCSP_MESSAGE_BUS_INFO *bus_info = (CCSP_MESSAGE_BUS_INFO *)bus_handle; + parameterValStruct_t upstream_param[1] = {0}; + + if(phyPath == NULL) { + CcspTraceInfo(("%s %d Error: phyPath is NULL \n", __FUNCTION__, __LINE__ )); + return ANSC_STATUS_FAILURE; + } + + strncpy(param_name, phyPath, sizeof(param_name)); + + if(strstr(param_name, "DSL") != NULL) { // dsl wan interface + strncat(param_name, DSL_UPSTREAM_NAME, sizeof(param_name)); + strncpy(pComponentName, DSL_COMPONENT_NAME, sizeof(pComponentName)); + strncpy(pComponentPath, DSL_COMPONENT_PATH, sizeof(pComponentPath)); + } + else if(strstr(param_name, "Ethernet") != NULL) { // ethernet wan interface + strncat(param_name, ETH_UPSTREAM_NAME, sizeof(param_name)); + strncpy(pComponentName, ETH_COMPONENT_NAME, sizeof(pComponentName)); + strncpy(pComponentPath, ETH_COMPONENT_PATH, sizeof(pComponentPath)); + } + if(flag) + strncpy(param_value, "true", sizeof(param_value)); + else + strncpy(param_value, "false", sizeof(param_value)); + + upstream_param[0].parameterName = param_name; + upstream_param[0].parameterValue = param_value; + upstream_param[0].type = ccsp_boolean; + + ret = CcspBaseIf_setParameterValues(bus_handle, pComponentName, pComponentPath, + 0, 0x0, /* session id and write id */ + upstream_param, 1, TRUE, /* Commit */ + &faultParam); + + if ( ( ret != CCSP_SUCCESS ) && ( faultParam )) { + CcspTraceInfo(("%s CcspBaseIf_setParameterValues failed with error %d\n",__FUNCTION__, ret )); + bus_info->freefunc( faultParam ); + return ANSC_STATUS_FAILURE; + } + + return ANSC_STATUS_SUCCESS; +} + + +static ANSC_STATUS WanMgr_RdkBus_GetParamNames( char *pComponent, char *pBus, char *pParamName, char a2cReturnVal[][BUFLEN_256], int *pReturnSize ) +{ + CCSP_MESSAGE_BUS_INFO *bus_info = (CCSP_MESSAGE_BUS_INFO *)bus_handle; + parameterInfoStruct_t **retInfo; + char *ParamName[ 1 ]; + int ret = 0, + nval; + + ret = CcspBaseIf_getParameterNames( + bus_handle, + pComponent, + pBus, + pParamName, + 1, + &nval, + &retInfo); + + //Copy the value + if( CCSP_SUCCESS == ret ) + { + int iLoopCount; + + *pReturnSize = nval; + + for( iLoopCount = 0; iLoopCount < nval; iLoopCount++ ) + { + if( NULL != retInfo[iLoopCount]->parameterName ) + { + //CcspTraceInfo(("%s parameterName[%d,%s]\n",__FUNCTION__,iLoopCount,retInfo[iLoopCount]->parameterName)); + snprintf( a2cReturnVal[iLoopCount], strlen( retInfo[iLoopCount]->parameterName ) + 1, "%s", retInfo[iLoopCount]->parameterName ); + } + } + + if( retInfo ) + { + free_parameterInfoStruct_t(bus_handle, nval, retInfo); + } + + return ANSC_STATUS_SUCCESS; + } + + if( retInfo ) + { + free_parameterInfoStruct_t(bus_handle, nval, retInfo); + } + + return ANSC_STATUS_FAILURE; +} + +ANSC_STATUS WanMgr_RdkBus_GetParamValues( char *pComponent, char *pBus, char *pParamName, char *pReturnVal ) +{ + CCSP_MESSAGE_BUS_INFO *bus_info = (CCSP_MESSAGE_BUS_INFO *)bus_handle; + parameterValStruct_t **retVal; + char *ParamName[ 1 ]; + int ret = 0, + nval; + + //Assign address for get parameter name + ParamName[0] = pParamName; + + ret = CcspBaseIf_getParameterValues( + bus_handle, + pComponent, + pBus, + ParamName, + 1, + &nval, + &retVal); + + //Copy the value + if( CCSP_SUCCESS == ret ) + { + //CcspTraceInfo(("%s parameterValue[%s]\n",__FUNCTION__,retVal[0]->parameterValue)); + + if( NULL != retVal[0]->parameterValue ) + { + memcpy( pReturnVal, retVal[0]->parameterValue, strlen( retVal[0]->parameterValue ) + 1 ); + } + + if( retVal ) + { + free_parameterValStruct_t (bus_handle, nval, retVal); + } + + return ANSC_STATUS_SUCCESS; + } + + if( retVal ) + { + free_parameterValStruct_t (bus_handle, nval, retVal); + } + + return ANSC_STATUS_FAILURE; +} + + + +ANSC_STATUS WanMgr_RdkBus_SetParamValues( char *pComponent, char *pBus, char *pParamName, char *pParamVal, enum dataType_e type, BOOLEAN bCommit ) +{ + CCSP_MESSAGE_BUS_INFO *bus_info = (CCSP_MESSAGE_BUS_INFO *)bus_handle; + parameterValStruct_t param_val[1] = { 0 }; + char *faultParam = NULL; + char acParameterName[BUFLEN_256] = { 0 }, + acParameterValue[BUFLEN_128] = { 0 }; + int ret = 0; + + //Copy Name + sprintf( acParameterName, "%s", pParamName ); + param_val[0].parameterName = acParameterName; + + //Copy Value + sprintf( acParameterValue, "%s", pParamVal ); + param_val[0].parameterValue = acParameterValue; + + //Copy Type + param_val[0].type = type; + + ret = CcspBaseIf_setParameterValues( + bus_handle, + pComponent, + pBus, + 0, + 0, + param_val, + 1, + bCommit, + &faultParam + ); + + if( ( ret != CCSP_SUCCESS ) && ( faultParam != NULL ) ) + { + CcspTraceError(("%s-%d Failed to set %s\n",__FUNCTION__,__LINE__,pParamName)); + bus_info->freefunc( faultParam ); + return ANSC_STATUS_FAILURE; + } + + return ANSC_STATUS_SUCCESS; +} + +/* * WanMgr_RdkBus_GetInterfaceInstanceInOtherAgent() */ +static ANSC_STATUS WanMgr_RdkBus_GetInterfaceInstanceInOtherAgent( WAN_NOTIFY_ENUM enNotifyAgent, char *pIfName, INT *piInstanceNumber ) +{ + //Validate buffer + if( ( NULL == pIfName ) || ( NULL == piInstanceNumber ) ) + { + CcspTraceError(("%s Invalid Buffer\n", __FUNCTION__)); + return ANSC_STATUS_FAILURE; + } + + //Initialise default value + *piInstanceNumber = -1; + + switch( enNotifyAgent ) + { + case NOTIFY_TO_VLAN_AGENT: + { + char acTmpReturnValue[BUFLEN_256] = { 0 }, + a2cTmpTableParams[10][BUFLEN_256] = { 0 }; + INT iLoopCount, + iTotalNoofEntries; + + if ( ANSC_STATUS_FAILURE == WanMgr_RdkBus_GetParamValues( VLAN_COMPONENT_NAME, VLAN_DBUS_PATH, VLAN_ETHLINK_NOE_PARAM_NAME, acTmpReturnValue ) ) + { + CcspTraceError(("%s %d Failed to get param value\n", __FUNCTION__, __LINE__)); + return ANSC_STATUS_FAILURE; + } + + //Total count + iTotalNoofEntries = atoi( acTmpReturnValue ); + CcspTraceInfo(("%s %d - TotalNoofEntries:%d\n", __FUNCTION__, __LINE__, iTotalNoofEntries)); + + if( 0 >= iTotalNoofEntries ) + { + return ANSC_STATUS_SUCCESS; + } + + //Get table names + iTotalNoofEntries = 0; + if ( ANSC_STATUS_FAILURE == WanMgr_RdkBus_GetParamNames( VLAN_COMPONENT_NAME, VLAN_DBUS_PATH, VLAN_ETHLINK_TABLE_NAME, a2cTmpTableParams , &iTotalNoofEntries )) + { + CcspTraceError(("%s %d Failed to get param value\n", __FUNCTION__, __LINE__)); + return ANSC_STATUS_FAILURE; + } + + //Traverse from loop + for ( iLoopCount = 0; iLoopCount < iTotalNoofEntries; iLoopCount++ ) + { + char acTmpQueryParam[BUFLEN_256] = { 0 }; + + //Query + snprintf( acTmpQueryParam, sizeof(acTmpQueryParam ), "%sAlias", a2cTmpTableParams[ iLoopCount ] ); + + memset( acTmpReturnValue, 0, sizeof( acTmpReturnValue ) ); + if ( ANSC_STATUS_FAILURE == WanMgr_RdkBus_GetParamValues( VLAN_COMPONENT_NAME, VLAN_DBUS_PATH, acTmpQueryParam, acTmpReturnValue ) ) + { + CcspTraceError(("%s %d Failed to get param value\n", __FUNCTION__, __LINE__)); + continue; + } + + //Compare ifname + if( 0 == strncmp(acTmpReturnValue, pIfName, BUFLEN_256) ) + { + char tmpTableParam[BUFLEN_256] = { 0 }; + const char *last_two; + + //Copy table param + snprintf( tmpTableParam, sizeof(tmpTableParam), "%s", a2cTmpTableParams[ iLoopCount ] ); + + //Get last two chareters from return value and cut the instance + last_two = &tmpTableParam[strlen(tmpTableParam) - 2]; + + *piInstanceNumber = atoi(last_two); + break; + } + } + } + break; /* * NOTIFY_TO_VLAN_AGENT */ + + default: + { + CcspTraceError(("%s Invalid Case\n", __FUNCTION__)); + } + break; /* * default */ + } + + return ANSC_STATUS_SUCCESS; +} + +/* * WanMgr_RdkBus_WanIfRefreshThread() */ +void* WanMgr_RdkBus_WanIfRefreshThread( void *arg ) +{ + DML_WAN_IFACE* pstWanIface = (DML_WAN_IFACE*)arg; + char acSetParamName[BUFLEN_256]; + INT iVLANInstance = -1; + + //Validate buffer + if( NULL == pstWanIface ) + { + CcspTraceError(("%s Invalid Memory\n", __FUNCTION__)); + pthread_exit(NULL); + } + + //detach thread from caller stack + pthread_detach(pthread_self()); + + //Need to sync with the state machine thread. + sleep(5); + + //Get Instance for corresponding name + WanMgr_RdkBus_GetInterfaceInstanceInOtherAgent( NOTIFY_TO_VLAN_AGENT, pstWanIface->Name, &iVLANInstance ); + + //Index is not present. so no need to do anything any VLAN instance + if( -1 != iVLANInstance ) + { + CcspTraceInfo(("%s %d VLAN Instance:%d\n",__FUNCTION__, __LINE__,iVLANInstance)); + + //Set VLAN EthLink Refresh + memset( acSetParamName, 0, sizeof(acSetParamName) ); + snprintf( acSetParamName, sizeof(acSetParamName), VLAN_ETHLINK_REFRESH_PARAM_NAME, iVLANInstance ); + WanMgr_RdkBus_SetParamValues( VLAN_COMPONENT_NAME, VLAN_DBUS_PATH, acSetParamName, "true", ccsp_boolean, TRUE ); + + CcspTraceInfo(("%s %d Successfully notified refresh event to VLAN Agent for %s interface[%s]\n", __FUNCTION__, __LINE__, pstWanIface->Name,acSetParamName)); + } + + //Free allocated resource + if( NULL != pstWanIface ) + { + free(pstWanIface); + pstWanIface = NULL; + } + + pthread_exit(NULL); + + return NULL; +} + +ANSC_STATUS DmlGetInstanceByKeywordFromPandM(char *ifname, int *piInstanceNumber) +{ + char acTmpReturnValue[256] = {0}; + int iLoopCount, + iTotalNoofEntries; + if (ANSC_STATUS_FAILURE == WanMgr_RdkBus_GetParamValues(PAM_COMPONENT_NAME, PAM_DBUS_PATH, PAM_NOE_PARAM_NAME, acTmpReturnValue)) + { + CcspTraceError(("[%s][%d]Failed to get param value\n", __FUNCTION__, __LINE__)); + return ANSC_STATUS_FAILURE; + } + + //Total count + iTotalNoofEntries = atoi(acTmpReturnValue); + + if ( 0 >= iTotalNoofEntries ) + { + return ANSC_STATUS_SUCCESS; + } + + //Traverse from loop + for (iLoopCount = 0; iLoopCount < iTotalNoofEntries; iLoopCount++) + { + char acTmpQueryParam[256] = {0}; + + //Query + snprintf(acTmpQueryParam, sizeof(acTmpQueryParam), PAM_IF_PARAM_NAME, iLoopCount + 1); + memset(acTmpReturnValue, 0, sizeof(acTmpReturnValue)); + if (ANSC_STATUS_FAILURE == WanMgr_RdkBus_GetParamValues(PAM_COMPONENT_NAME, PAM_DBUS_PATH, acTmpQueryParam, acTmpReturnValue)) + { + CcspTraceError(("[%s][%d] Failed to get param value\n", __FUNCTION__, __LINE__)); + continue; + } + + //Compare name + if (0 == strcmp(acTmpReturnValue, ifname)) + { + *piInstanceNumber = iLoopCount + 1; + break; + } + } + + return ANSC_STATUS_SUCCESS; +} diff --git a/source/TR-181/middle_layer_src/wanmgr_rdkbus_utils.h b/source/TR-181/middle_layer_src/wanmgr_rdkbus_utils.h new file mode 100644 index 00000000..2c106e14 --- /dev/null +++ b/source/TR-181/middle_layer_src/wanmgr_rdkbus_utils.h @@ -0,0 +1,92 @@ +#ifndef _WANMGR_RDKBUS_UTILS_H_ +#define _WANMGR_RDKBUS_UTILS_H_ + +/* + If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2020 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + + +/************************************************************************** + + module: wan_controller_utils.c + + For COSA Data Model Library Development + + ------------------------------------------------------------------- + + description: + + State machine to manage a Wan Controller + + ------------------------------------------------------------------- + + environment: + + platform independent + + ------------------------------------------------------------------- + + author: + + COSA XML TOOL CODE GENERATOR 1.0 + + ------------------------------------------------------------------- + + revision: + + 13/02/2020 initial revision. + +**************************************************************************/ + + +#include "dmsb_tr181_psm_definitions.h" +#include "ccsp_psm_helper.h" +#include "wanmgr_data.h" +#include "wanmgr_rdkbus_common.h" +#include "wanmgr_data.h" +#include "ansc_platform.h" +#include "platform_hal.h" + + +//VLAN Agent +#define VLAN_DBUS_PATH "/com/cisco/spvtg/ccsp/vlanmanager" +#define VLAN_COMPONENT_NAME "eRT.com.cisco.spvtg.ccsp.vlanmanager" +#define VLAN_ETHLINK_NOE_PARAM_NAME "Device.X_RDK_Ethernet.LinkNumberOfEntries" +#define VLAN_ETHLINK_TABLE_NAME "Device.X_RDK_Ethernet.Link." +#define VLAN_ETHLINK_REFRESH_PARAM_NAME "Device.X_RDK_Ethernet.Link.%d.X_RDK_Refresh" +//XDSL Manager +#define DSL_COMPONENT_NAME "eRT.com.cisco.spvtg.ccsp.xdslmanager" +#define DSL_COMPONENT_PATH "/com/cisco/spvtg/ccsp/xdslmanager" +#define DSL_UPSTREAM_NAME ".Upstream" +//Eth Manager +#define ETH_COMPONENT_NAME "eRT.com.cisco.spvtg.ccsp.ethagent" +#define ETH_COMPONENT_PATH "/com/cisco/spvtg/ccsp/ethagent" +#define ETH_UPSTREAM_NAME ".Upstream" + + +ANSC_STATUS WanMgr_RdkBus_SetParamValues( char *pComponent, char *pBus, char *pParamName, char *pParamVal, enum dataType_e type, BOOLEAN bCommit ); +ANSC_STATUS WanMgr_RdkBus_GetParamValues( char *pComponent, char *pBus, char *pParamName, char *pReturnVal ); + +ANSC_STATUS WanMgr_RdkBus_getWanPolicy(DML_WAN_POLICY *wan_policy); +ANSC_STATUS WanMgr_RdkBus_setWanPolicy(DML_WAN_POLICY wan_policy); +ANSC_STATUS WanMgr_RdkBus_updateInterfaceUpstreamFlag(char *phyPath, BOOL flag); +void* WanMgr_RdkBus_WanIfRefreshThread( void *arg ); + +ANSC_STATUS DmlGetInstanceByKeywordFromPandM(char *ifname, int *piInstanceNumber); + +#endif /* _WANMGR_RDKBUS_UTILS_H_ */ diff --git a/source/WanManager/Makefile.am b/source/WanManager/Makefile.am new file mode 100644 index 00000000..5637fc98 --- /dev/null +++ b/source/WanManager/Makefile.am @@ -0,0 +1,37 @@ +########################################################################## +# If not stated otherwise in this file or this component's Licenses.txt +# file the following copyright and licenses apply: +# +# Copyright 2017 RDK Management +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +########################################################################## + +bin_PROGRAMS = wanmanager + +AM_CPPFLAGS = -I$(top_srcdir)/hal/include \ + -I$(top_srcdir)/source/LogComponent \ + -I$(top_srcdir)/source/TR-181/middle_layer_src \ + -I$(top_srcdir)/source/TR-181/include \ + -I$(top_srcdir)/../CcspCommonLibrary/source/ccsp/components/include + + +wanmanager_DEPENDENCIES = \ + $(EXTRA_DEPENDENCIES) \ + ${top_builddir}/source/TR-181/middle_layer_src/libCcspWanManager_middle_layer_src.la + +wanmanager_CFLAGS = -D_ANSC_LINUX -D_ANSC_USER -D_ANSC_LITTLE_ENDIAN_ -DFEATURE_SUPPORT_RDKLOG $(DBUS_CFLAGS) $(SYSTEMD_CFLAGS) +wanmanager_SOURCES = wanmgr_main.c wanmgr_ssp_action.c wanmgr_ssp_messagebus_interface.c wanmgr_core.c wanmgr_controller.c wanmgr_data.c wanmgr_sysevents.c wanmgr_policy_fm_impl.c wanmgr_policy_fmob_impl.c wanmgr_policy_pp_impl.c wanmgr_policy_ppob_impl.c wanmgr_interface_sm.c wanmgr_platform_events.c wanmgr_utils.c wanmgr_net_utils.c wanmgr_dhcpv4_apis.c wanmgr_dhcpv6_apis.c wanmgr_ipc.c wanmgr_dhcpv4_internal.c wanmgr_dhcpv6_internal.c +wanmanager_LDFLAGS = -lccsp_common -lrdkloggers $(DBUS_LIBS) $(SYSTEMD_LDFLAGS) -lhal_platform -lapi_dhcpv4c +wanmanager_LDADD = $(wanmanager_DEPENDENCIES) + diff --git a/source/WanManager/wanmgr_controller.c b/source/WanManager/wanmgr_controller.c new file mode 100644 index 00000000..17f85076 --- /dev/null +++ b/source/WanManager/wanmgr_controller.c @@ -0,0 +1,156 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2015 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +#include "ansc_platform.h" +#include "wanmgr_controller.h" +#include "wanmgr_rdkbus_utils.h" +#include "wanmgr_data.h" + + +ANSC_STATUS WanController_Policy_Change(void) +{ + /* Wan policy changed. Cpe needs a restart! */ + FILE *fp = NULL; + char value[25] = {0}; + char cmd[128] = {0}; + char acOutput[64] = {0}; + int seconds = 30; + int rebootCount = 1; + + memset(value, 0, sizeof(value)); + fp = popen("syscfg get X_RDKCENTRAL-COM_LastRebootCounter", "r"); + if (fp == NULL) { + return ANSC_STATUS_FAILURE; + } + pclose(fp); + + rebootCount = atoi(value); + + CcspTraceInfo(("Updating the last reboot reason and last reboot counter\n")); + sprintf(cmd, "syscfg set X_RDKCENTRAL-COM_LastRebootReason Wan_Policy_Change "); + system(cmd); + sprintf(cmd, "syscfg set X_RDKCENTRAL-COM_LastRebootCounter %d ",rebootCount); + system(cmd); + system("syscfg commit"); + + while(seconds > 0) + { + printf("...(%d)...\n", seconds); + seconds -= 10; + sleep(10); + } + + system("/rdklogger/backupLogs.sh true"); + + return ANSC_STATUS_SUCCESS; +} + +/* WanController_Start_StateMachine() */ +ANSC_STATUS WanController_Start_StateMachine(DML_WAN_POLICY swan_policy) +{ + ANSC_STATUS retStatus = ANSC_STATUS_FAILURE; + DML_WAN_POLICY wan_policy = FIXED_MODE; + int iErrorCode = 0; + + CcspTraceInfo(("%s %d \n", __FUNCTION__, __LINE__ )); + + //Get Policy + WanMgr_Config_Data_t* pWanConfigData = WanMgr_GetConfigData_locked(); + if(pWanConfigData != NULL) + { + DML_WANMGR_CONFIG* pWanConfig = &(pWanConfigData->data); + + wan_policy = pWanConfig->Policy; + + WanMgrDml_GetConfigData_release(pWanConfigData); + } + + + //Starts wan controller threads + switch (wan_policy) { + case FIXED_MODE: + retStatus = WanMgr_Policy_FixedModePolicy(); + break; + + case FIXED_MODE_ON_BOOTUP: + retStatus = WanMgr_Policy_FixedModeOnBootupPolicy(); + break; + + case PRIMARY_PRIORITY: + retStatus = WanMgr_Policy_PrimaryPriorityPolicy(); + break; + + case PRIMARY_PRIORITY_ON_BOOTUP: + retStatus = WanMgr_Policy_PrimaryPriorityOnBootupPolicy(); + break; + + case MULTIWAN_MODE: + break; + } + + if( ANSC_STATUS_SUCCESS != retStatus ) + { + CcspTraceInfo(("%s %d Error: Failed to start State Machine Thread error code: %d \n", __FUNCTION__, __LINE__, retStatus )); + retStatus = ANSC_STATUS_SUCCESS; + } + + WanController_Policy_Change(); + + return retStatus; +} + +/* WanController_Init_StateMachine */ +ANSC_STATUS WanController_Init_StateMachine(void) +{ + int iTotalInterfaces = 0; + DML_WAN_POLICY wan_policy; + + CcspTraceInfo(("%s %d \n", __FUNCTION__, __LINE__ )); + + // Get the configured wan policy + if(WanMgr_RdkBus_getWanPolicy(&wan_policy) != ANSC_STATUS_SUCCESS) { + CcspTraceInfo(("%s %d Error: WanController_getWanPolicy() failed \n", __FUNCTION__, __LINE__ )); + return ANSC_STATUS_FAILURE; + } + + if(WanController_Start_StateMachine(wan_policy) != ANSC_STATUS_SUCCESS) { + CcspTraceInfo(("%s %d Error: WanController_Start_StateMachine failed \n", __FUNCTION__, __LINE__ )); + return ANSC_STATUS_FAILURE; + } + + return ANSC_STATUS_SUCCESS; +} + + +ANSC_STATUS WanMgr_Controller_PolicyCtrlInit(WanMgr_Policy_Controller_t* pWanPolicyCtrl) +{ + ANSC_STATUS retStatus = ANSC_STATUS_FAILURE; + + if(pWanPolicyCtrl != NULL) + { + pWanPolicyCtrl->WanEnable = FALSE; + pWanPolicyCtrl->activeInterfaceIdx = -1; + pWanPolicyCtrl->selSecondaryInterfaceIdx = -1; + pWanPolicyCtrl->pWanActiveIfaceData = NULL; + + retStatus = ANSC_STATUS_SUCCESS; + } + + return retStatus; +} diff --git a/source/WanManager/wanmgr_controller.h b/source/WanManager/wanmgr_controller.h new file mode 100644 index 00000000..d82e3d1c --- /dev/null +++ b/source/WanManager/wanmgr_controller.h @@ -0,0 +1,47 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2015 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + + +#ifndef _WANMGR_CONTROLLER_H_ +#define _WANMGR_CONTROLLER_H_ +#include "ansc_platform.h" +#include "ansc_load_library.h" +#include "wanmgr_data.h" + +typedef struct _WANMGR_POLICY_CONTROLLER_ +{ + BOOL WanEnable; + INT activeInterfaceIdx; + INT selSecondaryInterfaceIdx; + WanMgr_Iface_Data_t* pWanActiveIfaceData; +} WanMgr_Policy_Controller_t; + + +ANSC_STATUS WanController_Init_StateMachine(void); +ANSC_STATUS WanController_Policy_Change(void); +ANSC_STATUS WanMgr_Controller_PolicyCtrlInit(WanMgr_Policy_Controller_t* pWanPolicyCtrl); + + +/* Policies routines */ +ANSC_STATUS WanMgr_Policy_FixedModePolicy(void); +ANSC_STATUS WanMgr_Policy_FixedModeOnBootupPolicy(void); +ANSC_STATUS WanMgr_Policy_PrimaryPriorityPolicy(void); +ANSC_STATUS WanMgr_Policy_PrimaryPriorityOnBootupPolicy(void); + +#endif /*_WANMGR_CONTROLLER_H_*/ diff --git a/source/WanManager/wanmgr_core.c b/source/WanManager/wanmgr_core.c new file mode 100644 index 00000000..6ca68c76 --- /dev/null +++ b/source/WanManager/wanmgr_core.c @@ -0,0 +1,65 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2017 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + + + +#include "wanmgr_core.h" +#include "wanmgr_sysevents.h" +#include "wanmgr_rdkbus_apis.h" + + +ANSC_STATUS WanMgr_Core_Init(void) +{ + ANSC_STATUS retStatus = ANSC_STATUS_SUCCESS; + + //Initialise system messages + retStatus = WanMgr_SysEvents_Init(); + if(retStatus != ANSC_STATUS_SUCCESS) + { + CcspTraceInfo(("%s %d - WanManager failed to initialise!\n", __FUNCTION__, __LINE__ )); + } + + //Starts the IPC thread + retStatus = WanMgr_StartIpcServer(); + if(retStatus != ANSC_STATUS_SUCCESS) + { + CcspTraceInfo(("%s %d - IPC Thread failed to start!\n", __FUNCTION__, __LINE__ )); + } + + return retStatus; +} + +ANSC_STATUS WanMgr_Core_Start(void) +{ + ANSC_STATUS retStatus = ANSC_STATUS_SUCCESS; + + //Initialise Policy State Machine + WanController_Init_StateMachine(); + + return retStatus; +} + +ANSC_STATUS WanMgr_Core_Finalise(void) +{ + ANSC_STATUS retStatus = ANSC_STATUS_SUCCESS; + + retStatus = WanMgr_SysEvents_Finalise(); + + return retStatus; +} diff --git a/source/WanManager/wanmgr_core.h b/source/WanManager/wanmgr_core.h new file mode 100644 index 00000000..673da6eb --- /dev/null +++ b/source/WanManager/wanmgr_core.h @@ -0,0 +1,38 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2015 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + + +#ifndef _WANMGR_CORE_H_ +#define _WANMGR_CORE_H_ + +#include "ansc_platform.h" + +/********************************************************************** + STRUCTURE AND CONSTANT DEFINITIONS +**********************************************************************/ + + +/********************************************************************** + FUNCTION PROTOTYPES +**********************************************************************/ +ANSC_STATUS WanMgr_Core_Init(void); +ANSC_STATUS WanMgr_Core_Start(void); +ANSC_STATUS WanMgr_Core_Finalise(void); + +#endif //_WANMGR_CORE_H_ \ No newline at end of file diff --git a/source/WanManager/wanmgr_data.c b/source/WanManager/wanmgr_data.c new file mode 100644 index 00000000..3b0036f1 --- /dev/null +++ b/source/WanManager/wanmgr_data.c @@ -0,0 +1,254 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2019 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + + +#include "wanmgr_data.h" + + +/******** WAN MGR DATABASE ********/ +static WANMGR_DATA_ST gWanMgrDataBase; + + + +/******** WANMGR CONFIG FUNCTIONS ********/ +WanMgr_Config_Data_t* WanMgr_GetConfigData_locked(void) +{ + WanMgr_Config_Data_t* pWanConfigData = &(gWanMgrDataBase.Config); + + //lock + if(pthread_mutex_lock(&(pWanConfigData->mDataMutex)) == 0) + { + return pWanConfigData; + } + + return NULL; +} + +void WanMgrDml_GetConfigData_release(WanMgr_Config_Data_t* pWanConfigData) +{ + if(pWanConfigData != NULL) + { + pthread_mutex_unlock (&(pWanConfigData->mDataMutex)); + } +} + +void WanMgr_SetConfigData_Default(DML_WANMGR_CONFIG* pWanDmlConfig) +{ + if(pWanDmlConfig != NULL) + { + pWanDmlConfig->Enable = TRUE; + pWanDmlConfig->Policy = FIXED_MODE; + pWanDmlConfig->IdleTimeout = 0; + } +} + + + +/******** WANMGR IFACE CTRL FUNCTIONS ********/ +WanMgr_IfaceCtrl_Data_t* WanMgr_GetIfaceCtrl_locked(void) +{ + WanMgr_IfaceCtrl_Data_t* pWanIfaceCtrl = &(gWanMgrDataBase.IfaceCtrl); + + //lock + if(pthread_mutex_lock(&(pWanIfaceCtrl->mDataMutex)) == 0) + { + return pWanIfaceCtrl; + } + + return NULL; +} + +void WanMgrDml_GetIfaceCtrl_release(WanMgr_IfaceCtrl_Data_t* pWanIfaceCtrl) +{ + if(pWanIfaceCtrl != NULL) + { + pthread_mutex_unlock (&(pWanIfaceCtrl->mDataMutex)); + } +} + + +void WanMgr_SetIfaceCtrl_Default(WanMgr_IfaceCtrl_Data_t* pWanIfaceCtrl) +{ + if(pWanIfaceCtrl != NULL) + { + pWanIfaceCtrl->ulTotalNumbWanInterfaces = 0; + pWanIfaceCtrl->pIface = NULL; + } +} + + +void WanMgr_IfaceCtrl_Delete(WanMgr_IfaceCtrl_Data_t* pWanIfaceCtrl) +{ + + if(pWanIfaceCtrl != NULL) + { + pWanIfaceCtrl->ulTotalNumbWanInterfaces = 0; + if(pWanIfaceCtrl->pIface != NULL) + { + AnscFreeMemory(pWanIfaceCtrl->pIface); + pWanIfaceCtrl->pIface = NULL; + } + } +} + +/******** WANMGR IFACE FUNCTIONS ********/ +WanMgr_Iface_Data_t* WanMgr_GetIfaceData_locked(UINT iface_index) +{ + WanMgr_IfaceCtrl_Data_t* pWanIfaceCtrl = WanMgr_GetIfaceCtrl_locked(); + if(pWanIfaceCtrl != NULL) + { + if(iface_index < pWanIfaceCtrl->ulTotalNumbWanInterfaces) + { + if(pWanIfaceCtrl->pIface != NULL) + { + WanMgr_Iface_Data_t* pWanIfaceData = &(pWanIfaceCtrl->pIface[iface_index]); + return pWanIfaceData; + } + } + + WanMgrDml_GetIfaceCtrl_release(pWanIfaceCtrl); + } + + return NULL; +} + +WanMgr_Iface_Data_t* WanMgr_GetIfaceDataByName_locked(char* iface_name) +{ + UINT idx; + + WanMgr_IfaceCtrl_Data_t* pWanIfaceCtrl = WanMgr_GetIfaceCtrl_locked(); + if(pWanIfaceCtrl != NULL) + { + if(pWanIfaceCtrl->pIface != NULL) + { + for(idx = 0; idx < pWanIfaceCtrl->ulTotalNumbWanInterfaces; idx++) + { + WanMgr_Iface_Data_t* pWanIfaceData = &(pWanIfaceCtrl->pIface[idx]); + + if(!strcmp(iface_name, pWanIfaceData->data.Wan.Name)) + { + return pWanIfaceData; + } + } + } + + WanMgrDml_GetIfaceCtrl_release(pWanIfaceCtrl); + } + + return NULL; +} + +void WanMgrDml_GetIfaceData_release(WanMgr_Iface_Data_t* pWanIfaceData) +{ + WanMgrDml_GetIfaceCtrl_release(&(gWanMgrDataBase.IfaceCtrl)); +} + +void WanMgr_IfaceData_Init(WanMgr_Iface_Data_t* pIfaceData, UINT iface_index) +{ + if(pIfaceData != NULL) + { + DML_WAN_IFACE* pWanDmlIface = &(pIfaceData->data); + + pWanDmlIface->uiIfaceIdx = iface_index; + pWanDmlIface->uiInstanceNumber = iface_index+1; + memset(pWanDmlIface->Name, 0, 64); + memset(pWanDmlIface->DisplayName, 0, 64); + memset(pWanDmlIface->Phy.Path, 0, 64); + pWanDmlIface->Phy.Status = WAN_IFACE_PHY_STATUS_DOWN; + memset(pWanDmlIface->Wan.Name, 0, 64); + pWanDmlIface->Wan.Enable = FALSE; + pWanDmlIface->Wan.Priority = -1; + pWanDmlIface->Wan.Type = WAN_IFACE_TYPE_UNCONFIGURED; + pWanDmlIface->Wan.SelectionTimeout = 0; + pWanDmlIface->Wan.EnableMAPT = FALSE; + pWanDmlIface->Wan.EnableDSLite = FALSE; + pWanDmlIface->Wan.EnableIPoE = FALSE; + pWanDmlIface->Wan.ActiveLink = FALSE; + pWanDmlIface->Wan.Status = WAN_IFACE_STATUS_DISABLED; + pWanDmlIface->Wan.LinkStatus = WAN_IFACE_LINKSTATUS_DOWN; + pWanDmlIface->Wan.Refresh = FALSE; + pWanDmlIface->Wan.Validation.DiscoverOffer = FALSE; + pWanDmlIface->Wan.Validation.SolicitAdvertise = FALSE; + pWanDmlIface->Wan.Validation.RS_RA = FALSE; + pWanDmlIface->Wan.Validation.PadiPado = FALSE; + pWanDmlIface->DynamicTrigger.Enable = FALSE; + pWanDmlIface->DynamicTrigger.Delay = 0; + memset(pWanDmlIface->IP.Path, 0, 64); + pWanDmlIface->IP.Ipv4Status = WAN_IFACE_IPV4_STATE_DOWN; + pWanDmlIface->IP.Ipv6Status = WAN_IFACE_IPV6_STATE_DOWN; + pWanDmlIface->IP.Ipv4Changed = FALSE; + pWanDmlIface->IP.Ipv6Changed = FALSE; + memset(&(pWanDmlIface->IP.Ipv4Data), 0, sizeof(WANMGR_IPV4_DATA)); + memset(&(pWanDmlIface->IP.Ipv6Data), 0, sizeof(WANMGR_IPV6_DATA)); + pWanDmlIface->IP.pIpcIpv4Data = NULL; + pWanDmlIface->IP.pIpcIpv6Data = NULL; + pWanDmlIface->MAP.MaptStatus = WAN_IFACE_MAPT_STATE_DOWN; + memset(pWanDmlIface->MAP.Path, 0, 64); + pWanDmlIface->MAP.MaptChanged = FALSE; + memset(pWanDmlIface->DSLite.Path, 0, 64); + pWanDmlIface->DSLite.Status = WAN_IFACE_DSLITE_STATE_DOWN; + pWanDmlIface->DSLite.Changed = FALSE; + pWanDmlIface->PPP.LinkStatus = WAN_IFACE_PPP_LINK_STATUS_DOWN; + pWanDmlIface->PPP.LCPStatus = WAN_IFACE_LCP_STATUS_DOWN; + pWanDmlIface->PPP.IPCPStatus = WAN_IFACE_IPCP_STATUS_DOWN; + pWanDmlIface->PPP.IPV6CPStatus = WAN_IFACE_IPV6CP_STATUS_DOWN; + } +} + +/******** WAN MGR DATA FUNCTIONS ********/ +void WanMgr_Data_Init(void) +{ + WANMGR_DATA_ST* pWanMgrData = &gWanMgrDataBase; + pthread_mutexattr_t muttex_attr; + + //Initialise mutex attributes + pthread_mutexattr_init(&muttex_attr); + pthread_mutexattr_settype(&muttex_attr, PTHREAD_MUTEX_RECURSIVE); + + /*** WAN CONFIG ***/ + WanMgr_SetConfigData_Default(&(pWanMgrData->Config.data)); + pthread_mutex_init(&(pWanMgrData->Config.mDataMutex), &(muttex_attr)); + + /*** WAN IFACE ***/ + WanMgr_SetIfaceCtrl_Default(&(pWanMgrData->IfaceCtrl)); + pthread_mutex_init(&(pWanMgrData->IfaceCtrl.mDataMutex), &(muttex_attr)); +} + + + + +ANSC_STATUS WanMgr_Data_Delete(void) +{ + ANSC_STATUS result = ANSC_STATUS_FAILURE; + WANMGR_DATA_ST* pWanMgrData = &gWanMgrDataBase; + int idx; + + /*** WAN CONFIG ***/ + pthread_mutex_destroy(&(pWanMgrData->Config.mDataMutex)); + + /*** WAN IFACE ***/ + + /*** WAN IFACECTRL ***/ + WanMgr_IfaceCtrl_Delete(&(pWanMgrData->IfaceCtrl)); + pthread_mutex_destroy(&(pWanMgrData->IfaceCtrl.mDataMutex)); + + return result; +} + + diff --git a/source/WanManager/wanmgr_data.h b/source/WanManager/wanmgr_data.h new file mode 100644 index 00000000..9405d76a --- /dev/null +++ b/source/WanManager/wanmgr_data.h @@ -0,0 +1,85 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2019 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +#ifndef _WANMGR_DATA_H_ +#define _WANMGR_DATA_H_ + +#include +#include "ansc_platform.h" +#include "ansc_string_util.h" +#include "wanmgr_dml.h" + +//WAN CONFIG +typedef struct _WANMGR_CONFIG_DATA_ +{ + DML_WANMGR_CONFIG data; + pthread_mutex_t mDataMutex; +} WanMgr_Config_Data_t; + + +//WAN IFACE +typedef struct _WANMGR_IFACE_DATA_ +{ + DML_WAN_IFACE data; +}WanMgr_Iface_Data_t; + + +typedef struct _WANMGR_IFACECTRL_DATA_ +{ + UINT ulTotalNumbWanInterfaces; + WanMgr_Iface_Data_t* pIface; + pthread_mutex_t mDataMutex; +}WanMgr_IfaceCtrl_Data_t; + + + +typedef struct _WANMGR_DATA_ST_ +{ + //WAN CONFIG + WanMgr_Config_Data_t Config; + + //WAN IFACE + WanMgr_IfaceCtrl_Data_t IfaceCtrl; +} WANMGR_DATA_ST; + + +//WAN CONFIG +WanMgr_Config_Data_t* WanMgr_GetConfigData_locked(void); +void WanMgrDml_GetConfigData_release(WanMgr_Config_Data_t* pWanConfigData); +void WanMgr_SetConfigData_Default(DML_WANMGR_CONFIG* pWanDmlConfig); + +//WAN IFACE +WanMgr_Iface_Data_t* WanMgr_GetIfaceData_locked(UINT iface_index); +WanMgr_Iface_Data_t* WanMgr_GetIfaceDataByName_locked(char* iface_name); +void WanMgrDml_GetIfaceData_release(WanMgr_Iface_Data_t* pWanIfaceData); +void WanMgr_IfaceData_Init(WanMgr_Iface_Data_t* pIfaceData, UINT uiInstNumber); + + +//WAN IFACE CTRL +WanMgr_IfaceCtrl_Data_t* WanMgr_GetIfaceCtrl_locked(void); +void WanMgrDml_GetIfaceCtrl_release(WanMgr_IfaceCtrl_Data_t* pWanIfaceCtrl); +void WanMgr_SetIfaceCtrl_Default(WanMgr_IfaceCtrl_Data_t* pWanIfaceCtrl); + +// WAN MGR +void WanMgr_Data_Init(void); +ANSC_STATUS WanMgr_Data_Delete(void); + + + +#endif //_WANMGR_DATA_H_ diff --git a/source/WanManager/wanmgr_dhcpv4_apis.c b/source/WanManager/wanmgr_dhcpv4_apis.c new file mode 100644 index 00000000..760ee350 --- /dev/null +++ b/source/WanManager/wanmgr_dhcpv4_apis.c @@ -0,0 +1,976 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2019 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ +#include "wanmgr_data.h" +#include "wanmgr_dhcpv4_apis.h" +#include "wanmgr_interface_sm.h" +#include "wanmgr_sysevents.h" +#include "wanmgr_ipc.h" +#include "wanmgr_utils.h" +#include "wanmgr_rdkbus_apis.h" +#include "wanmgr_dhcpv4_internal.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "dhcpv4c_api.h" +#include +#include +#include + + +#include "ccsp_psm_helper.h" +#include "sysevent/sysevent.h" +#include "dmsb_tr181_psm_definitions.h" + +#include "cJSON.h" + + +extern int sysevent_fd; +extern token_t sysevent_token; +extern PWAN_DHCPV4_DATA g_pDhcpv4; + +extern WANMGR_BACKEND_OBJ* g_pWanMgrBE; + +#define COSA_DHCP4_SYSCFG_NAMESPACE NULL + +DML_DHCPC_FULL CH_g_dhcpv4_client[DML_DHCP_MAX_ENTRIES]; +COSA_DML_DHCP_OPT g_dhcpv4_client_sent[DML_DHCP_MAX_ENTRIES][DML_DHCP_MAX_OPT_ENTRIES]; +DML_DHCPC_REQ_OPT g_dhcpv4_client_req[DML_DHCP_MAX_ENTRIES][DML_DHCP_MAX_OPT_ENTRIES]; + +ULONG g_Dhcp4ClientNum = 0; +ULONG g_Dhcp4ClientSentOptNum[DML_DHCP_MAX_ENTRIES] = {0,0,0,0}; +ULONG g_Dhcp4ClientReqOptNum[DML_DHCP_MAX_ENTRIES] = {0,0,0,0}; + +// for PSM access +extern ANSC_HANDLE bus_handle; +extern char g_Subsystem[32]; + +#define P2P_SUB_NET_MASK "255.255.255.255" +#define DHCP_STATE_UP "Up" +#define DHCP_STATE_DOWN "Down" + +static ANSC_STATUS wanmgr_dchpv4_get_ipc_msg_info(WANMGR_IPV4_DATA* pDhcpv4Data, ipc_dhcpv4_data_t* pIpcIpv4Data) +{ + if((pDhcpv4Data == NULL) || (pIpcIpv4Data == NULL)) + { + return ANSC_STATUS_FAILURE; + } + memcpy(pDhcpv4Data->ifname, pIpcIpv4Data->dhcpcInterface, BUFLEN_64); + memcpy(pDhcpv4Data->ip, pIpcIpv4Data->ip, BUFLEN_32); + memcpy(pDhcpv4Data->mask , pIpcIpv4Data->mask, BUFLEN_32); + memcpy(pDhcpv4Data->gateway, pIpcIpv4Data->gateway, BUFLEN_32); + memcpy(pDhcpv4Data->dnsServer, pIpcIpv4Data->dnsServer, BUFLEN_64); + memcpy(pDhcpv4Data->dnsServer1, pIpcIpv4Data->dnsServer1, BUFLEN_64); + + return ANSC_STATUS_SUCCESS; +} + + +ANSC_STATUS wanmgr_handle_dchpv4_event_data(DML_WAN_IFACE* pIfaceData) +{ + if(NULL == pIfaceData) + { + return ANSC_STATUS_FAILURE; + } + + ipc_dhcpv4_data_t* pDhcpcInfo = pIfaceData->IP.pIpcIpv4Data; + if(NULL == pDhcpcInfo) + { + return ANSC_STATUS_BAD_PARAMETER; + } + + CcspTraceInfo(("%s %d - Enter \n", __FUNCTION__, __LINE__)); + bool IPv4ConfigChanged = FALSE; + + + if (strcmp(pIfaceData->IP.Ipv4Data.ip, pDhcpcInfo->ip) || + strcmp(pIfaceData->IP.Ipv4Data.mask, pDhcpcInfo->mask) || + strcmp(pIfaceData->IP.Ipv4Data.gateway, pDhcpcInfo->gateway) || + strcmp(pIfaceData->IP.Ipv4Data.dnsServer, pDhcpcInfo->dnsServer) || + strcmp(pIfaceData->IP.Ipv4Data.dnsServer1, pDhcpcInfo->dnsServer1)) + { + CcspTraceInfo(("%s %d - IPV4 configuration changed \n", __FUNCTION__, __LINE__)); + IPv4ConfigChanged = TRUE; + } + + char name[64] = {0}; + char value[64] = {0}; + uint32_t up_time = 0; + + /* ipv4_start_time should be set in every v4 packets */ + snprintf(name,sizeof(name),SYSEVENT_IPV4_START_TIME,pDhcpcInfo->dhcpcInterface); + up_time = WanManager_getUpTime(); + snprintf(value, sizeof(value), "%u", up_time); + sysevent_set(sysevent_fd, sysevent_token, name, value, 0); + + if (pDhcpcInfo->addressAssigned) + { + CcspTraceInfo(("assigned ip=%s netmask=%s gateway=%s dns server=%s,%s leasetime = %d, rebindtime = %d, renewaltime = %d, dhcp state = %s\n", + pDhcpcInfo->ip, + pDhcpcInfo->mask, + pDhcpcInfo->gateway, + pDhcpcInfo->dnsServer, + pDhcpcInfo->dnsServer1, + pDhcpcInfo->leaseTime, + pDhcpcInfo->rebindingTime, + pDhcpcInfo->renewalTime, + pDhcpcInfo->dhcpState)); + + if (IPv4ConfigChanged) + { + if (wanmgr_sysevents_ipv4Info_set(pDhcpcInfo, pDhcpcInfo->dhcpcInterface) != ANSC_STATUS_SUCCESS) + { + CcspTraceError(("%s %d - Could not store ipv4 data!", __FUNCTION__, __LINE__)); + } + //Update isIPv4ConfigChanged flag. + pIfaceData->IP.Ipv4Changed = TRUE; + } + else + { + CcspTraceInfo(("%s %d - IPV4 optional configuration received \n", __FUNCTION__, __LINE__)); + snprintf(name, sizeof(name), SYSEVENT_IPV4_DS_CURRENT_RATE, pDhcpcInfo->dhcpcInterface); + snprintf(value, sizeof(value), "%d", pDhcpcInfo->downstreamCurrRate); + sysevent_set(sysevent_fd, sysevent_token, name, value, 0); + + snprintf(name, sizeof(name), SYSEVENT_IPV4_US_CURRENT_RATE, pDhcpcInfo->dhcpcInterface); + snprintf(value, sizeof(value), "%d", pDhcpcInfo->upstreamCurrRate); + sysevent_set(sysevent_fd, sysevent_token, name, value, 0); + + snprintf(name, sizeof(name), SYSEVENT_IPV4_LEASE_TIME, pDhcpcInfo->dhcpcInterface); + snprintf(value, sizeof(value), "%d", pDhcpcInfo->leaseTime); + sysevent_set(sysevent_fd, sysevent_token, name, value, 0); + + if (pDhcpcInfo->isTimeOffsetAssigned) + { + snprintf(value, sizeof(value), "@%d", pDhcpcInfo->timeOffset); + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_IPV4_TIME_OFFSET, value, 0); + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_DHCPV4_TIME_OFFSET, SET, 0); + } + else + { + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_DHCPV4_TIME_OFFSET, UNSET, 0); + } + + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_IPV4_TIME_ZONE, pDhcpcInfo->timeZone, 0); + } + + // update current IPv4 data + wanmgr_dchpv4_get_ipc_msg_info(&(pIfaceData->IP.Ipv4Data), pDhcpcInfo); + WanManager_UpdateInterfaceStatus(pIfaceData, WANMGR_IFACE_CONNECTION_UP); + } + else if (pDhcpcInfo->isExpired) + { + CcspTraceInfo(("DHCPC Lease expired!!!!!!!!!!\n")); + // update current IPv4 data + wanmgr_dchpv4_get_ipc_msg_info(&(pIfaceData->IP.Ipv4Data), pDhcpcInfo); + WanManager_UpdateInterfaceStatus(pIfaceData, WANMGR_IFACE_CONNECTION_DOWN); + } + + + if (pIfaceData->IP.pIpcIpv4Data != NULL ) + { + //free memory + free(pIfaceData->IP.pIpcIpv4Data); + pIfaceData->IP.pIpcIpv4Data = NULL; + } + + return ANSC_STATUS_SUCCESS; +} + +void* IPCPStateChangeHandler (void *arg) +{ + char acTmpReturnValue[256] = {0}; + char acTmpQueryParam[256] = {0}; + char *token = NULL; + int index = -1; + + const char *dhcpcInterface = (char *) arg; + if(NULL == dhcpcInterface) + { + return ANSC_STATUS_FAILURE; + } + pthread_detach(pthread_self()); + + //get iface data + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceDataByName_locked(dhcpcInterface); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pIfaceData = &(pWanDmlIfaceData->data); + + // Get PPP instance number + sscanf(pIfaceData->PPP.Path, "%*[^0-9]%d", &index); + + //check if previously message was already handled + if(pIfaceData->IP.pIpcIpv4Data == NULL) + { + //allocate + pIfaceData->IP.pIpcIpv4Data = (ipc_dhcpv4_data_t*) malloc(sizeof(ipc_dhcpv4_data_t)); + if(pIfaceData->IP.pIpcIpv4Data != NULL) + { + switch (pIfaceData->PPP.IPCPStatus) + { + case WAN_IFACE_IPCP_STATUS_UP: + { + pIfaceData->IP.pIpcIpv4Data->isExpired = FALSE; + pIfaceData->IP.pIpcIpv4Data->addressAssigned = TRUE; + strncpy (pIfaceData->IP.pIpcIpv4Data->dhcpState, DHCP_STATE_UP, BUFLEN_64); + + //Query for Local IP address + snprintf( acTmpQueryParam, sizeof(acTmpQueryParam ), PPP_IPCP_LOCAL_IPADDRESS, index ); + memset( acTmpReturnValue, 0, sizeof( acTmpReturnValue ) ); + if ( ANSC_STATUS_FAILURE == WanMgr_RdkBus_GetParamValues( PPPMGR_COMPONENT_NAME, PPPMGR_DBUS_PATH, acTmpQueryParam, acTmpReturnValue ) ) + { + CcspTraceError(("%s %d Failed to get param value for paramname %s \n", __FUNCTION__, __LINE__, acTmpQueryParam)); + goto EXIT; + } + if (acTmpReturnValue[0] != '\0') + { + strncpy (pIfaceData->IP.pIpcIpv4Data->ip, acTmpReturnValue, BUFLEN_32); + } + else + { + strncpy (pIfaceData->IP.pIpcIpv4Data->dhcpState, DHCP_STATE_DOWN, BUFLEN_64); + pIfaceData->IP.pIpcIpv4Data->addressAssigned = FALSE; + } + + //Query for Remote IP address + snprintf( acTmpQueryParam, sizeof(acTmpQueryParam ), PPP_IPCP_REMOTEIPADDRESS, index ); + memset( acTmpReturnValue, 0, sizeof( acTmpReturnValue ) ); + if ( ANSC_STATUS_FAILURE == WanMgr_RdkBus_GetParamValues( PPPMGR_COMPONENT_NAME, PPPMGR_DBUS_PATH, acTmpQueryParam, acTmpReturnValue ) ) + { + CcspTraceError(("%s %d Failed to get param value for paramname %s \n", __FUNCTION__, __LINE__, acTmpQueryParam)); + goto EXIT; + } + if (acTmpReturnValue[0] != '\0') + { + strncpy (pIfaceData->IP.pIpcIpv4Data->gateway, acTmpReturnValue, BUFLEN_32); + } + else + { + strncpy (pIfaceData->IP.pIpcIpv4Data->dhcpState, DHCP_STATE_DOWN, BUFLEN_64); + pIfaceData->IP.pIpcIpv4Data->addressAssigned = FALSE; + } + //Query for DNS Servers + snprintf( acTmpQueryParam, sizeof(acTmpQueryParam ), PPP_IPCP_DNS_SERVERS, index ); + memset( acTmpReturnValue, 0, sizeof( acTmpReturnValue ) ); + if ( ANSC_STATUS_FAILURE == WanMgr_RdkBus_GetParamValues( PPPMGR_COMPONENT_NAME, PPPMGR_DBUS_PATH, acTmpQueryParam, acTmpReturnValue ) ) + { + CcspTraceError(("%s %d Failed to get param value for paramname %s \n", __FUNCTION__, __LINE__, acTmpQueryParam)); + goto EXIT; + } + if (acTmpReturnValue[0] != '\0') + { + //Return first DNS Server + token = strtok(acTmpReturnValue, ","); + if (token != NULL) + { + strcpy (pIfaceData->IP.pIpcIpv4Data->dnsServer, token ); + //Return first DNS Server + token = strtok(NULL, ","); + if (token != NULL) + { + strcpy (pIfaceData->IP.pIpcIpv4Data->dnsServer1, token); + } + } + } + + strncpy (pIfaceData->IP.pIpcIpv4Data->dhcpcInterface, dhcpcInterface, BUFLEN_64); + strncpy (pIfaceData->IP.pIpcIpv4Data->mask, P2P_SUB_NET_MASK, BUFLEN_32); + wanmgr_handle_dchpv4_event_data(pIfaceData); + break; + } + case WAN_IFACE_IPCP_STATUS_DOWN: + { + strncpy (pIfaceData->IP.pIpcIpv4Data->dhcpcInterface, dhcpcInterface, BUFLEN_64); + strncpy (pIfaceData->IP.pIpcIpv4Data->dhcpState, DHCP_STATE_DOWN, BUFLEN_64); + pIfaceData->IP.pIpcIpv4Data->addressAssigned = FALSE; + wanmgr_handle_dchpv4_event_data(pIfaceData); + break; + } + } + + } + } + + } + +EXIT: + if(pWanDmlIfaceData != NULL) + { + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + if (arg != NULL) + { + free(arg); + } + + return NULL; +} + +static ANSC_STATUS DhcpcDmlScan() +{ + CHAR tmpBuff[64] = {0}; + CHAR tmp[3][64]; + CHAR ip[32]; + CHAR subnet[32]; + CHAR str_val[64] = {0}; + CHAR str_key[64] = {0}; + CHAR dns[3][32] = {"","",""}; + CHAR line[128]; + char *tok; + int nmu_dns_server = 0; + FILE *fp = NULL; + + PDML_DHCPC_FULL pEntry = NULL; + + ULONG ulIndex = 0; + + g_Dhcp4ClientNum = 0; + + for (ulIndex = 0; ulIndex < 2; ulIndex++) + { + if (ulIndex == 0) + { + fp = fopen("/tmp/udhcp.log", "r"); + } + else if (ulIndex == 1) + { + + /*RDKB-6750, CID-33082, free resources before exit*/ + if(fp) + { + fclose(fp); + fp = NULL; + } + +#ifdef _COSA_DRG_TPG_ + fp = fopen("/tmp/udhcp_lan.log", "r"); +#else + return ANSC_STATUS_SUCCESS; +#endif + + } + pEntry = &CH_g_dhcpv4_client[ulIndex]; + + if (!fp) + { + return ANSC_STATUS_FAILURE; + } + + while ( fgets(line, sizeof(line), fp) ) + { + memset(str_key, 0, sizeof(str_key)); + memset(str_val, 0, sizeof(str_val)); + + tok = strtok( line, ":"); + if(tok) strncpy(str_key, tok, sizeof(str_key)-1 ); + + tok = strtok(NULL, ":"); + while( tok && (tok[0] == ' ') ) tok++; /*RDKB-6750, CID-33384, CID-32954; null check before use*/ + if(tok) strncpy(str_val, tok, sizeof(str_val)-1 ); + + if ( str_val[ _ansc_strlen(str_val) - 1 ] == '\n' ) + { + str_val[ _ansc_strlen(str_val) - 1 ] = '\0'; + } + + if( !strcmp(str_key, "interface ") ) + { + AnscCopyString( pEntry->Cfg.Interface, str_val); + } + else if( !strcmp(str_key, "ip address ") ) + { + sscanf(str_val, "%s", ip); + AnscWriteUlong(&pEntry->Info.IPAddress.Value, _ansc_inet_addr(ip)); + } + else if( !strcmp(str_key, "subnet mask ") ) + { + sscanf(str_val, "%s", subnet ); + AnscWriteUlong(&pEntry->Info.SubnetMask.Value, _ansc_inet_addr(subnet)); + } + else if( !strcmp(str_key, "lease time ") ) + { + pEntry->Info.LeaseTimeRemaining = atoi(str_val); + } + else if( !strcmp(str_key, "router ") ) + { + sscanf(str_val, "%s", ip ); + AnscWriteUlong(&pEntry->Info.IPRouters[0].Value, _ansc_inet_addr(ip) ); + } + else if( !strcmp(str_key, "server id ") ) + { + sscanf(str_val, "%s", ip ); + AnscWriteUlong(&pEntry->Info.DHCPServer.Value, _ansc_inet_addr(ip)); + } + else if( !strcmp(str_key, "dns server ") ) + { + nmu_dns_server = 0; + char *tok; + + tok = strtok( str_val, " "); + if(tok) strncpy(dns[0], tok, sizeof(dns[0])-1 ); + if( dns[0] ) + { + ++nmu_dns_server; + AnscWriteUlong(&pEntry->Info.DNSServers[0].Value, _ansc_inet_addr(dns[0])); + } + while( tok != NULL) + { + tok = strtok(NULL, " "); + if(tok) strncpy(dns[nmu_dns_server], tok, sizeof(dns[nmu_dns_server])-1 ); + if (strlen(dns[nmu_dns_server]) > 1 ) + { + AnscWriteUlong(&pEntry->Info.DNSServers[nmu_dns_server].Value, _ansc_inet_addr(dns[nmu_dns_server])); + ++nmu_dns_server; + if( nmu_dns_server > 2) /*RDKB-6750, CID-33057, Fixing Out-of-bounds read of dns[3][] */ + nmu_dns_server = 2; + } + } + } + } + + if ( !_ansc_strncmp(pEntry->Cfg.Interface, DML_DHCP_CLIENT_IFNAME, _ansc_strlen(DML_DHCP_CLIENT_IFNAME)) ) + { + memset(tmpBuff, 0, sizeof(tmpBuff)); + syscfg_get(NULL, "tr_dhcp4_instance_wan", tmpBuff, sizeof(tmpBuff)); + CH_g_dhcpv4_client[ulIndex].Cfg.InstanceNumber = atoi(tmpBuff); + + memset(tmpBuff, 0, sizeof(tmpBuff)); + syscfg_get(NULL, "tr_dhcp4_alias_wan", tmpBuff, sizeof(tmpBuff)); + AnscCopyString(CH_g_dhcpv4_client[ulIndex].Cfg.Alias, tmpBuff); + } + else if ( !_ansc_strncmp(pEntry->Cfg.Interface, "lan0", _ansc_strlen("lan0")) ) + { + memset(tmpBuff, 0, sizeof(tmpBuff)); + syscfg_get(NULL, "tr_dhcp4_instance_lan", tmpBuff, sizeof(tmpBuff)); + CH_g_dhcpv4_client[ulIndex].Cfg.InstanceNumber = atoi(tmpBuff); + + memset(tmpBuff, 0, sizeof(tmpBuff)); + syscfg_get(NULL, "tr_dhcp4_alias_lan", tmpBuff, sizeof(tmpBuff)); + AnscCopyString(CH_g_dhcpv4_client[ulIndex].Cfg.Alias, tmpBuff); + } + + pEntry->Cfg.PassthroughEnable = FALSE; + + //AnscCopyString( pEntry->Cfg.PassthroughDHCPPool, ""); + pEntry->Cfg.bEnabled = TRUE; + //pEntry->Cfg.bRenew = FALSE; + + pEntry->Info.Status = DML_DHCP_STATUS_Enabled; + pEntry->Info.DHCPStatus = DML_DHCPC_STATUS_Bound; + + pEntry->Info.NumIPRouters = 1; + pEntry->Info.NumDnsServers = nmu_dns_server; + g_Dhcp4ClientNum++; + + } + fclose(fp); + return ANSC_STATUS_SUCCESS; +} + +/* + Description: + The API retrieves the number of DHCP clients in the system. + */ +ULONG +WanMgr_DmlDhcpcGetNumberOfEntries + ( + ANSC_HANDLE hContext + ) +{ + UNREFERENCED_PARAMETER(hContext); + return 1; +} + +/* + Description: + The API retrieves the complete info of the DHCP clients designated by index. The usual process is the caller gets the total number of entries, then iterate through those by calling this API. + Arguments: + ulIndex Indicates the index number of the entry. + pEntry To receive the complete info of the entry. +*/ +ANSC_STATUS WanMgr_DmlDhcpcGetEntry ( ANSC_HANDLE hContext, ULONG ulIndex, PDML_DHCPC_FULL pEntry ) +{ + UNREFERENCED_PARAMETER(hContext); + if(ulIndex >0) + return(ANSC_STATUS_FAILURE); + pEntry->Cfg.InstanceNumber = 1; + WanMgr_DmlDhcpcGetCfg(hContext, &pEntry->Cfg); + WanMgr_DmlDhcpcGetInfo(hContext, ulIndex,&pEntry->Info); + return ANSC_STATUS_SUCCESS; +} + +/* + Function Name: WanMgr_DmlDhcpcSetValues + Description: + The API set the the DHCP clients' instance number and alias to the syscfg DB. + Arguments: + ulIndex Indicates the index number of the entry. + ulInstanceNumber Client's Instance number + pAlias pointer to the Client's Alias +*/ +ANSC_STATUS WanMgr_DmlDhcpcSetValues + ( + ANSC_HANDLE hContext, + ULONG ulIndex, + ULONG ulInstanceNumber, + char* pAlias + ) +{ + UNREFERENCED_PARAMETER(hContext); + UNREFERENCED_PARAMETER(ulIndex); + UNREFERENCED_PARAMETER(ulInstanceNumber); + UNREFERENCED_PARAMETER(pAlias); + return ANSC_STATUS_FAILURE; +} + +/* + Description: + The API adds DHCP client. + Arguments: + pEntry Caller fills in pEntry->Cfg, except Alias field. Upon return, callee fills pEntry->Cfg.Alias field and as many as possible fields in pEntry->Info. +*/ +ANSC_STATUS WanMgr_DmlDhcpcAddEntry ( ANSC_HANDLE hContext, ULONG pInsNumber ) +{ + PDHCPC_CONTEXT_LINK_OBJECT pCxtLink = NULL; + PDML_DHCPC_FULL pDhcpc = NULL; + PWAN_DHCPV4_DATA pDhcpv4 = (PWAN_DHCPV4_DATA)g_pWanMgrBE->hDhcpv4; + ULONG i = 0; + + UNREFERENCED_PARAMETER(hContext); + if (pDhcpv4 != NULL) + { + pDhcpc = (PDML_DHCPC_FULL)AnscAllocateMemory( sizeof(DML_DHCPC_FULL) ); + if ( !pDhcpc ) + { + return NULL; /* return the handle */ + } + + /* Set default value */ + DHCPV4_CLIENT_SET_DEFAULTVALUE(pDhcpc); + + /* Add into our link tree*/ + pCxtLink = (PDHCPC_CONTEXT_LINK_OBJECT)AnscAllocateMemory( sizeof(DHCPC_CONTEXT_LINK_OBJECT) ); + if ( !pDhcpc ) + { + AnscFreeMemory(pDhcpc); + return NULL; + } + + DHCPV4_CLIENT_INITIATION_CONTEXT(pCxtLink) + + pCxtLink->hContext = (ANSC_HANDLE)pDhcpc; + pCxtLink->bNew = TRUE; + + if ( !++pDhcpv4->maxInstanceOfClient ) + { + pDhcpv4->maxInstanceOfClient = 1; + } + pDhcpc->Cfg.InstanceNumber = pDhcpv4->maxInstanceOfClient; + pCxtLink->InstanceNumber = pDhcpc->Cfg.InstanceNumber; + + _ansc_sprintf( pDhcpc->Cfg.Alias, "Client%d", pDhcpc->Cfg.InstanceNumber); + + /* Put into our list */ + SListPushEntryByInsNum(&pDhcpv4->ClientList, (PCONTEXT_LINK_OBJECT)pCxtLink); + + /* we recreate the configuration because we has new delay_added entry for dhcpv4 */ + WanMgr_Dhcpv4RegSetDhcpv4Info(pDhcpv4); + } + return pCxtLink; +} + +/* + Description: + The API removes the designated DHCP client entry. + Arguments: + pAlias The entry is identified through Alias. +*/ +ANSC_STATUS +WanMgr_DmlDhcpcDelEntry + ( + ANSC_HANDLE hContext, + ULONG ulInstanceNumber + ) +{ + UNREFERENCED_PARAMETER(hContext); + UNREFERENCED_PARAMETER(ulInstanceNumber); + return ANSC_STATUS_FAILURE; +} + +/* +Description: + The API re-configures the designated DHCP client entry. +Arguments: + pAlias The entry is identified through Alias. + pEntry The new configuration is passed through this argument, even Alias field can be changed. +*/ + +ANSC_STATUS +WanMgr_DmlDhcpcSetCfg + ( + ANSC_HANDLE hContext, + PDML_DHCPC_CFG pCfg + ) +{ + UNREFERENCED_PARAMETER(hContext); + UNREFERENCED_PARAMETER(pCfg); + ULONG index = 0; + /*don't allow to change dhcp configuration*/ + + return ANSC_STATUS_FAILURE; +} + +ANSC_STATUS +WanMgr_DmlDhcpcGetCfg + ( + ANSC_HANDLE hContext, + PDML_DHCPC_CFG pCfg + ) +{ + UNREFERENCED_PARAMETER(hContext); + ULONG i = 0; + char ifname[32]; + + if ( !pCfg ) + { + return ANSC_STATUS_FAILURE; + } + + sprintf(pCfg->Alias,"eRouter"); + pCfg->bEnabled = TRUE; + pCfg->InstanceNumber = 1; + if(dhcpv4c_get_ert_ifname(ifname)) + pCfg->Interface[0] = 0; + else + sprintf(pCfg->Interface,"%s", ifname); + pCfg->PassthroughEnable = TRUE; + pCfg->PassthroughDHCPPool[0] = 0; + + return ANSC_STATUS_SUCCESS; +} + +ANSC_STATUS +WanMgr_DmlDhcpcGetInfo + ( + ANSC_HANDLE hContext, + ULONG ulInstanceNumber, + PDML_DHCPC_INFO pInfo + ) +{ + UNREFERENCED_PARAMETER(hContext); + ULONG index = 0; + ANSC_STATUS rc; + dhcpv4c_ip_list_t address; + int i; + + if ( (!pInfo) || (ulInstanceNumber != 1) ){ + return ANSC_STATUS_FAILURE; + } + + pInfo->Status = DML_DHCP_STATUS_Enabled; + dhcpv4c_get_ert_fsm_state((int*)&pInfo->DHCPStatus); + dhcpv4c_get_ert_ip_addr((unsigned int*)&pInfo->IPAddress.Value); + dhcpv4c_get_ert_mask((unsigned int*)&pInfo->SubnetMask.Value); + pInfo->NumIPRouters = 1; + dhcpv4c_get_ert_gw((unsigned int*)&pInfo->IPRouters[0].Value); + address.number = 0; + dhcpv4c_get_ert_dns_svrs(&address); + pInfo->NumDnsServers = address.number; + if (pInfo->NumDnsServers > DML_DHCP_MAX_ENTRIES) + { + CcspTraceError(("!!! Max DHCP Entry Overflow: %d",address.number)); + pInfo->NumDnsServers = DML_DHCP_MAX_ENTRIES; // Fail safe + } + for(i=0; i< pInfo->NumDnsServers;i++) + pInfo->DNSServers[i].Value = address.addrs[i]; + dhcpv4c_get_ert_remain_lease_time((unsigned int*)&pInfo->LeaseTimeRemaining); + dhcpv4c_get_ert_dhcp_svr((unsigned int*)&pInfo->DHCPServer); + + return ANSC_STATUS_SUCCESS; +} + +/* + Description: + The API initiates a DHCP client renewal. + Arguments: + pAlias The entry is identified through Alias. +*/ +ANSC_STATUS +WanMgr_DmlDhcpcRenew + ( + ANSC_HANDLE hContext, + ULONG ulInstanceNumber + ) +{ + UNREFERENCED_PARAMETER(hContext); + if(ulInstanceNumber != 1) + return(ANSC_STATUS_FAILURE); +#ifndef _HUB4_PRODUCT_REQ_ + system("sysevent set dhcp_client-renew"); +#endif + return(ANSC_STATUS_SUCCESS); +} + +/* + * DHCP Client Send/Req Option + * + * The options are managed on top of a DHCP client, + * which is identified through pClientAlias + */ + +static BOOL WanMgr_DmlDhcpcWriteOptions(ULONG ulClientInstanceNumber) +{ + UNREFERENCED_PARAMETER(ulClientInstanceNumber); + return FALSE; +} + + +ULONG +WanMgr_DmlDhcpcGetNumberOfSentOption + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber + ) +{ + UNREFERENCED_PARAMETER(hContext); + UNREFERENCED_PARAMETER(ulClientInstanceNumber); + return 0; +} + +ANSC_STATUS +WanMgr_DmlDhcpcGetSentOption + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber, + ULONG ulIndex, + PCOSA_DML_DHCP_OPT pEntry + ) +{ + UNREFERENCED_PARAMETER(hContext); + UNREFERENCED_PARAMETER(ulClientInstanceNumber); + UNREFERENCED_PARAMETER(ulIndex); + UNREFERENCED_PARAMETER(pEntry); + return ANSC_STATUS_FAILURE; +} + + +ANSC_STATUS +WanMgr_DmlDhcpcGetSentOptionbyInsNum + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber, + PCOSA_DML_DHCP_OPT pEntry + ) +{ + UNREFERENCED_PARAMETER(hContext); + ULONG index = 0; + ULONG i = 0; + + for(i = 0; i < g_Dhcp4ClientNum; i++) + { + if ( CH_g_dhcpv4_client[i].Cfg.InstanceNumber == ulClientInstanceNumber) + { + for( index = 0; index < g_Dhcp4ClientSentOptNum[i]; index++) + { + if ( pEntry->InstanceNumber == g_dhcpv4_client_sent[i][index].InstanceNumber ) + { + AnscCopyMemory( pEntry, &g_dhcpv4_client_sent[i][index], sizeof(COSA_DML_DHCP_OPT)); + return ANSC_STATUS_SUCCESS; + } + } + } + } + + return ANSC_STATUS_FAILURE; +} + +ANSC_STATUS +WanMgr_DmlDhcpcSetSentOptionValues + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber, + ULONG ulIndex, + ULONG ulInstanceNumber, + char* pAlias + ) +{ + UNREFERENCED_PARAMETER(hContext); + return ANSC_STATUS_FAILURE; +} + +ANSC_STATUS +WanMgr_DmlDhcpcAddSentOption + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber, + PCOSA_DML_DHCP_OPT pEntry + ) +{ + UNREFERENCED_PARAMETER(hContext); + UNREFERENCED_PARAMETER(ulClientInstanceNumber); + UNREFERENCED_PARAMETER(pEntry); + return ANSC_STATUS_FAILURE; +} + + + +ANSC_STATUS +WanMgr_DmlDhcpcDelSentOption + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber, + ULONG ulInstanceNumber + ) +{ + UNREFERENCED_PARAMETER(hContext); + UNREFERENCED_PARAMETER(ulClientInstanceNumber); + UNREFERENCED_PARAMETER(ulInstanceNumber); + return ANSC_STATUS_FAILURE; +} + + +ANSC_STATUS +WanMgr_DmlDhcpcSetSentOption + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber, + PCOSA_DML_DHCP_OPT pEntry + ) +{ + UNREFERENCED_PARAMETER(hContext); + UNREFERENCED_PARAMETER(ulClientInstanceNumber); + UNREFERENCED_PARAMETER(pEntry); + return ANSC_STATUS_FAILURE; +} + +/* + * DHCP Client Send/Req Option + * + * The options are managed on top of a DHCP client, + * which is identified through pClientAlias + */ +ULONG +WanMgr_DmlDhcpcGetNumberOfReqOption + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber + ) +{ + UNREFERENCED_PARAMETER(hContext); + UNREFERENCED_PARAMETER(ulClientInstanceNumber); + return 0; +} + +ANSC_STATUS +WanMgr_DmlDhcpcGetReqOption + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber, + ULONG ulIndex, + PDML_DHCPC_REQ_OPT pEntry + ) +{ + UNREFERENCED_PARAMETER(hContext); + UNREFERENCED_PARAMETER(ulClientInstanceNumber); + UNREFERENCED_PARAMETER(ulIndex); + UNREFERENCED_PARAMETER(pEntry); + return ANSC_STATUS_FAILURE; +} + +ANSC_STATUS +WanMgr_DmlDhcpcGetReqOptionbyInsNum + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber, + PDML_DHCPC_REQ_OPT pEntry + ) +{ + UNREFERENCED_PARAMETER(hContext); + UNREFERENCED_PARAMETER(ulClientInstanceNumber); + UNREFERENCED_PARAMETER(pEntry); + return ANSC_STATUS_FAILURE; +} + +ANSC_STATUS +WanMgr_DmlDhcpcSetReqOptionValues + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber, + ULONG ulIndex, + ULONG ulInstanceNumber, + char* pAlias + ) +{ + UNREFERENCED_PARAMETER(hContext); + UNREFERENCED_PARAMETER(ulClientInstanceNumber); + UNREFERENCED_PARAMETER(ulIndex); + UNREFERENCED_PARAMETER(ulInstanceNumber); + UNREFERENCED_PARAMETER(pAlias); + return ANSC_STATUS_FAILURE; +} + + +ANSC_STATUS +WanMgr_DmlDhcpcAddReqOption + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber, + PDML_DHCPC_REQ_OPT pEntry + ) +{ + UNREFERENCED_PARAMETER(hContext); + UNREFERENCED_PARAMETER(ulClientInstanceNumber); + UNREFERENCED_PARAMETER(pEntry); + return ANSC_STATUS_FAILURE; +} + +ANSC_STATUS +WanMgr_DmlDhcpcDelReqOption + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber, + ULONG ulInstanceNumber + ) +{ + UNREFERENCED_PARAMETER(hContext); + UNREFERENCED_PARAMETER(ulClientInstanceNumber); + UNREFERENCED_PARAMETER(ulInstanceNumber); + return ANSC_STATUS_FAILURE; +} + +ANSC_STATUS +WanMgr_DmlDhcpcSetReqOption + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber, + PDML_DHCPC_REQ_OPT pEntry + ) +{ + UNREFERENCED_PARAMETER(hContext); + UNREFERENCED_PARAMETER(ulClientInstanceNumber); + UNREFERENCED_PARAMETER(pEntry); + return ANSC_STATUS_FAILURE; +} diff --git a/source/WanManager/wanmgr_dhcpv4_apis.h b/source/WanManager/wanmgr_dhcpv4_apis.h new file mode 100644 index 00000000..491b7036 --- /dev/null +++ b/source/WanManager/wanmgr_dhcpv4_apis.h @@ -0,0 +1,359 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2019 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +#ifndef _WANMGR_DHCPV4_APIS_H_ +#define _WANMGR_DHCPV4_APIS_H_ +#include +#include +#include +#include +#include +#include "wanmgr_dml.h" +#include "wanmgr_rdkbus_apis.h" +#include "wanmgr_rdkbus_common.h" + +#include "ansc_platform.h" +#include "ipc_msg.h" + +#define DHCPV4_CLIENT_NAME "udhcpc" +#define DHCPV4_ACTION_HANDLER "service_udhcpc" +#define DML_ALIAS_NAME_LENGTH 64 + +/** + * @brief API to process DHCP state change event message. + * @param msg - Pointer to msg_payload_t structure contains Dhcpv4 configuration as part of ipc message + * @return ANSC_STATUS_SUCCESS upon success else error code returned. + */ +ANSC_STATUS wanmgr_handle_dchpv4_event_data(DML_WAN_IFACE* pIfaceData); +void* IPCPStateChangeHandler (void *arg); + +/********************************************************************** + STRUCTURE AND CONSTANT DEFINITIONS +**********************************************************************/ + +#define DML_DHCP_MAX_ENTRIES 4 +#define DML_DHCP_MAX_RESERVED_ADDRESSES 8 +#define DML_DHCP_MAX_OPT_ENTRIES 8 + +#define _DEBUG_DHCPV4 +#ifdef _DEBUG_DHCPV4 + #define ULOGF ulogf +#else + #define ULOGF +#endif + +typedef enum +_DML_DHCP_STATUS +{ + DML_DHCP_STATUS_Disabled = 1, + DML_DHCP_STATUS_Enabled, + DML_DHCP_STATUS_Error_Misconfigured, + DML_DHCP_STATUS_Error +} +DML_DHCP_STATUS, *PDML_DHCP_STATUS; + + +typedef enum +_DML_DHCPC_STATUS +{ + DML_DHCPC_STATUS_Init = 1, + DML_DHCPC_STATUS_Selecting, + DML_DHCPC_STATUS_Requesting, + DML_DHCPC_STATUS_Rebinding, + DML_DHCPC_STATUS_Bound, + DML_DHCPC_STATUS_Renewing +} +DML_DHCPC_STATUS, *PDML_DHCPC_STATUS; + + +typedef struct +_COSA_DML_DHCP_OPT +{ + ULONG InstanceNumber; + char Alias[512]; + + BOOLEAN bEnabled; + UCHAR Tag; + UCHAR Value[255]; +} +COSA_DML_DHCP_OPT, *PCOSA_DML_DHCP_OPT; + + +/* + * DHCP Client + */ +typedef struct +_DML_DHCPC_CFG +{ + ULONG InstanceNumber; + char Alias[DML_ALIAS_NAME_LENGTH]; + + BOOLEAN bEnabled; + char Interface[DML_ALIAS_NAME_LENGTH]; /* IP interface name */ + BOOLEAN PassthroughEnable; + char PassthroughDHCPPool[64]; /* DHCP server pool alias */ + char X_CISCO_COM_BootFileName[256]; +} +DML_DHCPC_CFG, *PDML_DHCPC_CFG; + + +typedef struct +_DML_DHCPC_INFO +{ + DML_DHCP_STATUS Status; + DML_DHCPC_STATUS DHCPStatus; + ANSC_IPV4_ADDRESS IPAddress; + ANSC_IPV4_ADDRESS SubnetMask; + ULONG NumIPRouters; + ANSC_IPV4_ADDRESS IPRouters[DML_DHCP_MAX_ENTRIES]; + ULONG NumDnsServers; + ANSC_IPV4_ADDRESS DNSServers[DML_DHCP_MAX_ENTRIES]; + int LeaseTimeRemaining; + ANSC_IPV4_ADDRESS DHCPServer; +} +DML_DHCPC_INFO, *PDML_DHCPC_INFO; + + +typedef struct +_DML_DHCPC_FULL +{ + DML_DHCPC_CFG Cfg; + DML_DHCPC_INFO Info; +} +DML_DHCPC_FULL, *PDML_DHCPC_FULL; + + +typedef struct +_DML_DHCPC_REQ_OPT +{ + ULONG InstanceNumber; + char Alias[DML_ALIAS_NAME_LENGTH]; + + BOOLEAN bEnabled; + ULONG Order; + UCHAR Tag; + UCHAR Value[255]; +} +DML_DHCPC_REQ_OPT, *PDML_DHCPC_REQ_OPT; + +/********************************************************************** + FUNCTION PROTOTYPES +**********************************************************************/ + +ANSC_STATUS +WanMgr_DmlDhcpInit + ( + ANSC_HANDLE hDml, + PANSC_HANDLE phContext + ); + +/* + * DHCP Client + */ +ULONG +WanMgr_DmlDhcpcGetNumberOfEntries + ( + ANSC_HANDLE hContext + ); + +ANSC_STATUS +WanMgr_DmlDhcpcGetEntry + ( + ANSC_HANDLE hContext, + ULONG ulIndex, + PDML_DHCPC_FULL pEntry + ); + +ANSC_STATUS +WanMgr_DmlDhcpcSetValues + ( + ANSC_HANDLE hContext, + ULONG ulIndex, + ULONG ulInstanceNumber, + char* pAlias + ); + +ANSC_STATUS +WanMgr_DmlDhcpcAddEntry + ( + ANSC_HANDLE hContext, + ULONG ulInstanceNumber + ); + +ANSC_STATUS +WanMgr_DmlDhcpcDelEntry + ( + ANSC_HANDLE hContext, + ULONG ulInstanceNumber + ); + +ANSC_STATUS +WanMgr_DmlDhcpcSetCfg + ( + ANSC_HANDLE hContext, + PDML_DHCPC_CFG pCfg /* Identified by InstanceNumber */ + ); + +ANSC_STATUS +WanMgr_DmlDhcpcGetCfg + ( + ANSC_HANDLE hContext, + PDML_DHCPC_CFG pCfg /* Identified by InstanceNumber */ + ); + +ANSC_STATUS +WanMgr_DmlDhcpcGetInfo + ( + ANSC_HANDLE hContext, + ULONG ulInstanceNumber, + PDML_DHCPC_INFO pInfo + ); + +ANSC_STATUS +WanMgr_DmlDhcpcRenew + ( + ANSC_HANDLE hContext, + ULONG ulInstanceNumber + ); + +/* + * DHCP Client Send/Req Option + * + * The options are managed on top of a DHCP client, + * which is identified through pClientAlias + */ +ULONG +WanMgr_DmlDhcpcGetNumberOfSentOption + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber + ); + +ANSC_STATUS +WanMgr_DmlDhcpcGetSentOptionbyInsNum + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber, + PCOSA_DML_DHCP_OPT pEntry + ); + +ANSC_STATUS +WanMgr_DmlDhcpcGetSentOption + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber, + ULONG ulIndex, + PCOSA_DML_DHCP_OPT pEntry + ); + +ANSC_STATUS +WanMgr_DmlDhcpcSetSentOptionValues + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber, + ULONG ulIndex, + ULONG ulInstanceNumber, + char* pAlias + ); + +ANSC_STATUS +WanMgr_DmlDhcpcAddSentOption + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber, + PCOSA_DML_DHCP_OPT pEntry + ); + +ANSC_STATUS +WanMgr_DmlDhcpcDelSentOption + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber, + ULONG ulInstanceNumber + ); + +ANSC_STATUS +WanMgr_DmlDhcpcSetSentOption + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber, + PCOSA_DML_DHCP_OPT pEntry /* Identified by InstanceNumber */ + ); + +ULONG +WanMgr_DmlDhcpcGetNumberOfReqOption + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber + ); + +ANSC_STATUS +WanMgr_DmlDhcpcGetReqOptionbyInsNum + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber, + PDML_DHCPC_REQ_OPT pEntry + ); + +ANSC_STATUS +WanMgr_DmlDhcpcGetReqOption + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber, + ULONG ulIndex, + PDML_DHCPC_REQ_OPT pEntry + ); + +ANSC_STATUS +WanMgr_DmlDhcpcSetReqOptionValues + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber, + ULONG ulIndex, + ULONG ulInstanceNumber, + char* pAlias + ); + +ANSC_STATUS +WanMgr_DmlDhcpcAddReqOption + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber, + PDML_DHCPC_REQ_OPT pEntry + ); + +ANSC_STATUS +WanMgr_DmlDhcpcDelReqOption + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber, + ULONG ulInstanceNumber + ); + +ANSC_STATUS +WanMgr_DmlDhcpcSetReqOption + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber, + PDML_DHCPC_REQ_OPT pEntry /* Identified by InstanceNumber */ + ); + + + +#endif //_WANMGR_DHCPV4_APIS_H_ diff --git a/source/WanManager/wanmgr_dhcpv4_internal.c b/source/WanManager/wanmgr_dhcpv4_internal.c new file mode 100644 index 00000000..48f589be --- /dev/null +++ b/source/WanManager/wanmgr_dhcpv4_internal.c @@ -0,0 +1,1951 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2015 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +/********************************************************************** + Copyright [2014] [Cisco Systems, Inc.] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +**********************************************************************/ + +/************************************************************************** + + module: wan_dhcpv4_internal.c + + For COSA Data Model Library Development + + ------------------------------------------------------------------- + + description: + + This file implementes back-end apis for the COSA Data Model Library + + * WanMgr_Dhcpv4Create + * WanMgr_Dhcpv4Initialize + * WanMgr_Dhcpv4Remove + * WanMgr_Dhcpv4RegGetDhcpv4Info + * WanMgr_Dhcpv4RegSetDhcpv4Info + * WanMgr_Dhcpv4ClientHasDelayAddedChild + +**************************************************************************/ +#include "wanmgr_apis.h" +#include "wanmgr_dhcpv4_apis.h" +#include "wanmgr_dhcpv4_internal.h" +#include "wanmgr_plugin_main_apis.h" +#include "poam_irepfo_interface.h" +#include "sys_definitions.h" + +extern void * g_pDslhDmlAgent; +PWAN_DHCPV4_DATA g_pDhcpv4; + + +/********************************************************************** + + caller: owner of the object + + prototype: + + ANSC_HANDLE + WanMgr_Dhcpv4Create + ( + ); + + description: + + This function constructs cosa nat object and return handle. + + argument: + + return: newly created nat object. + +**********************************************************************/ + +ANSC_HANDLE WanMgr_Dhcpv4Create ( VOID ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PWAN_DHCPV4_DATA pMyObject = (PWAN_DHCPV4_DATA) NULL; + + /* + * We create object by first allocating memory for holding the variables and member functions. + */ + pMyObject = (PWAN_DHCPV4_DATA)AnscAllocateMemory(sizeof(WAN_DHCPV4_DATA)); + if ( pMyObject == NULL ) + { + return (ANSC_HANDLE)NULL; + } + /* + * Initialize the common variables and functions for a container object. + */ + pMyObject->Oid = WAN_DHCPV4_DATA_OID; + pMyObject->Create = WanMgr_Dhcpv4Create; + pMyObject->Remove = WanMgr_Dhcpv4Remove; + pMyObject->Initialize = WanMgr_Dhcpv4Initialize; + + pMyObject->Initialize((ANSC_HANDLE)pMyObject); + + return (ANSC_HANDLE)pMyObject; +} + +/********************************************************************** + + caller: self + + prototype: + + ANSC_STATUS + WanMgr_Dhcpv4Initialize + ( + ANSC_HANDLE hThisObject + ); + + description: + + This function initiate cosa nat object and return handle. + + argument: ANSC_HANDLE hThisObject + This handle is actually the pointer of this object + itself. + + return: operation status. + +**********************************************************************/ + +ANSC_STATUS WanMgr_Dhcpv4Initialize ( ANSC_HANDLE hThisObject ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PWAN_DHCPV4_DATA pMyObject = (PWAN_DHCPV4_DATA) hThisObject; + + if (pMyObject == NULL) + { + AnscTraceError(("%s:%d:: Pointer is null!!\n", __FUNCTION__, __LINE__)); + return ANSC_STATUS_FAILURE; + } + /* Initiation all functions */ + AnscSListInitializeHeader( &pMyObject->ClientList ); + pMyObject->maxInstanceOfClient = 0; + AnscZeroMemory(pMyObject->AliasOfClient, sizeof(pMyObject->AliasOfClient)); + + /* We need get NextInstanceNumber from backend. By the way, the whole tree + was created. Moreover, we also need get delay-added entry and put them + into our tree. */ + WanMgr_Dhcpv4RegGetDhcpv4Info((ANSC_HANDLE)pMyObject); + + /* Firstly we create the whole system from backend */ + WanMgr_Dhcpv4BackendGetDhcpv4Info((ANSC_HANDLE)pMyObject); + + return returnStatus; +} + +/********************************************************************** + + caller: self + + prototype: + + ANSC_STATUS + WanMgr_Dhcpv4Remove + ( + ANSC_HANDLE hThisObject + ); + + description: + + This function initiate cosa nat object and return handle. + + argument: ANSC_HANDLE hThisObject + This handle is actually the pointer of this object + itself. + + return: operation status. + +**********************************************************************/ + +ANSC_STATUS WanMgr_Dhcpv4Remove ( ANSC_HANDLE hThisObject ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PWAN_DHCPV4_DATA pMyObject = (PWAN_DHCPV4_DATA)hThisObject; + + PDHCPC_CONTEXT_LINK_OBJECT pCxtDhcpcLink = NULL; + PCONTEXT_LINK_OBJECT pCxtLink = NULL; + PSINGLE_LINK_ENTRY pSListEntry = NULL; + PSINGLE_LINK_ENTRY pSListEntry2 = NULL; + + /* Remove necessary resource */ + + if (pMyObject != NULL) + { + AnscTraceError(("%s:%d:: Pointer is null!!\n", __FUNCTION__, __LINE__)); + return ANSC_STATUS_FAILURE; + } + pSListEntry = AnscSListPopEntry(&pMyObject->ClientList); + while( pSListEntry != NULL) + { + pCxtDhcpcLink = ACCESS_CONTEXT_DHCPC_LINK_OBJECT(pSListEntry); + pSListEntry = AnscSListGetNextEntry(pSListEntry); + + pSListEntry2 = AnscSListPopEntry(&pCxtDhcpcLink->SendOptionList); + while( pSListEntry2 != NULL) + { + pCxtLink = ACCESS_CONTEXT_LINK_OBJECT(pSListEntry2); + pSListEntry2 = AnscSListGetNextEntry(pSListEntry2); + + AnscFreeMemory(pCxtLink->hContext); + AnscFreeMemory(pCxtLink); + } + + pSListEntry2 = AnscSListPopEntry(&pCxtDhcpcLink->ReqOptionList); + while( pSListEntry2 != NULL) + { + pCxtLink = ACCESS_CONTEXT_LINK_OBJECT(pSListEntry2); + pSListEntry2 = AnscSListGetNextEntry(pSListEntry2); + + AnscFreeMemory(pCxtLink->hContext); + AnscFreeMemory(pCxtLink); + } + + AnscFreeMemory(pCxtDhcpcLink->hContext); + AnscFreeMemory(pCxtDhcpcLink); + } + + return returnStatus; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ANSC_STATUS + WanMgr_Dhcpv4RegGetDhcpv4Info + ( + ANSC_HANDLE hThisObject + ); + + description: + + This function is called to retrieve the NextInstanceNumber for every table, Create + the link tree. For delay_added entry, we also need create them. + + argument: ANSC_HANDLE hThisObject + This handle is actually the pointer of dhcpv4 + itself. + + return: status of operation. + +**********************************************************************/ + +ANSC_STATUS WanMgr_Dhcpv4BackendGetDhcpv4Info (ANSC_HANDLE hThisObject) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PWAN_DHCPV4_DATA pDhcpv4 = (PWAN_DHCPV4_DATA)hThisObject; + + PDML_DHCPC_FULL pDhcpc = NULL; + PDML_DHCPC_REQ_OPT pReqOption = NULL; + PCOSA_DML_DHCP_OPT pSendOption = NULL; + ULONG clientCount = 0; + ULONG count = 0; + ULONG ulIndex = 0; + ULONG ulIndex2 = 0; + + PDHCPC_CONTEXT_LINK_OBJECT pClientCxtLink = NULL; + PDHCPC_CONTEXT_LINK_OBJECT pClientCxtLink2 = NULL; + PCONTEXT_LINK_OBJECT pCxtLink = NULL; + PCONTEXT_LINK_OBJECT pCxtLink2 = NULL; + BOOL bNeedSave = FALSE; + + /* Get DHCPv4.Client.{i} */ + clientCount = WanMgr_DmlDhcpcGetNumberOfEntries(NULL); + for ( ulIndex = 0; ulIndex < clientCount; ulIndex++ ) + { + pDhcpc = (PDML_DHCPC_FULL)AnscAllocateMemory( sizeof(DML_DHCPC_FULL) ); + if ( !pDhcpc ) + { + break; + } + + DHCPV4_CLIENT_SET_DEFAULTVALUE(pDhcpc); + returnStatus = WanMgr_DmlDhcpcGetEntry(NULL, ulIndex, pDhcpc); + if ( returnStatus != ANSC_STATUS_SUCCESS ) + { + AnscFreeMemory(pDhcpc); + break; + } + + pClientCxtLink = (PDHCPC_CONTEXT_LINK_OBJECT)AnscAllocateMemory( sizeof(DHCPC_CONTEXT_LINK_OBJECT) ); + if ( !pClientCxtLink ) + { + AnscFreeMemory(pDhcpc); + break; + } + + DHCPV4_CLIENT_INITIATION_CONTEXT(pClientCxtLink) + pClientCxtLink->hContext = (ANSC_HANDLE)pDhcpc; + pClientCxtLink->bNew = FALSE; + + if ( !pDhcpc->Cfg.InstanceNumber ) + { + if ( !++pDhcpv4->maxInstanceOfClient ) + { + pDhcpv4->maxInstanceOfClient = 1; + } + bNeedSave = TRUE; + + pDhcpc->Cfg.InstanceNumber = pDhcpv4->maxInstanceOfClient; + pClientCxtLink->InstanceNumber = pDhcpc->Cfg.InstanceNumber; + + _ansc_sprintf(pDhcpc->Cfg.Alias, "DHCPv4%lu", pDhcpc->Cfg.InstanceNumber); + + returnStatus = WanMgr_DmlDhcpcSetValues + ( + NULL, + ulIndex, + pDhcpc->Cfg.InstanceNumber, + pDhcpc->Cfg.Alias + ); + + if ( returnStatus != ANSC_STATUS_SUCCESS ) + { + AnscFreeMemory(pDhcpc); + AnscFreeMemory(pClientCxtLink); + break; + } + + /* Put into our list */ + SListPushEntryByInsNum(&pDhcpv4->ClientList, (PCONTEXT_LINK_OBJECT)pClientCxtLink); + } + else + { + pClientCxtLink->InstanceNumber = pDhcpc->Cfg.InstanceNumber; + + /* This case never happen. Add it just for simulation code run well */ + if ( pDhcpv4->maxInstanceOfClient < pClientCxtLink->InstanceNumber ) + { + pDhcpv4->maxInstanceOfClient = pClientCxtLink->InstanceNumber; + bNeedSave = TRUE; + } + + /* if this entry is in link tree already because it's the parent of delay_added table */ + pClientCxtLink2 = (PDHCPC_CONTEXT_LINK_OBJECT)SListGetEntryByInsNum(&pDhcpv4->ClientList, pClientCxtLink->InstanceNumber); + if ( !pClientCxtLink2 ) + { + SListPushEntryByInsNum(&pDhcpv4->ClientList, (PCONTEXT_LINK_OBJECT)pClientCxtLink); + } + else + { + AnscFreeMemory( pClientCxtLink2->hContext ); + pClientCxtLink2->hContext = (ANSC_HANDLE)pDhcpc; + if ( pClientCxtLink2->bNew ) + { + pClientCxtLink2->bNew = FALSE; + bNeedSave = TRUE; + } + + AnscFreeMemory(pClientCxtLink); + pClientCxtLink = pClientCxtLink2; + pClientCxtLink2 = NULL; + } + } + + /* We begin treat DHCPv4.Client.{i}.ReqOption.{i} */ + count = WanMgr_DmlDhcpcGetNumberOfReqOption + ( + NULL, + pDhcpc->Cfg.InstanceNumber + ); + + for ( ulIndex2 = 0; ulIndex2 < count; ulIndex2++ ) + { + pReqOption = (PDML_DHCPC_REQ_OPT)AnscAllocateMemory( sizeof(DML_DHCPC_REQ_OPT) ); + if ( !pReqOption ) + { + break; + } + + DHCPV4_REQOPTION_SET_DEFAULTVALUE(pReqOption); + returnStatus = WanMgr_DmlDhcpcGetReqOption + ( + NULL, + pDhcpc->Cfg.InstanceNumber, + ulIndex2, + pReqOption + ); + if ( returnStatus != ANSC_STATUS_SUCCESS ) + { + AnscFreeMemory(pReqOption); + break; + } + + pCxtLink = (PCONTEXT_LINK_OBJECT)AnscAllocateMemory( sizeof(CONTEXT_LINK_OBJECT) ); + if ( !pCxtLink ) + { + AnscFreeMemory(pReqOption); + break; + } + + CONTEXT_LINK_INITIATION_CONTENT(pCxtLink); + pCxtLink->hContext = (ANSC_HANDLE)pReqOption; + pCxtLink->hParentTable = (ANSC_HANDLE)pClientCxtLink; + pCxtLink->bNew = FALSE; + + if ( !pReqOption->InstanceNumber ) + { + if ( !++pClientCxtLink->maxInstanceOfReq ) + { + pClientCxtLink->maxInstanceOfReq = 1; + } + bNeedSave = TRUE; + + pReqOption->InstanceNumber = pClientCxtLink->maxInstanceOfReq; + + _ansc_sprintf( pReqOption->Alias, "ReqOption%lu", pReqOption->InstanceNumber ); + + returnStatus = WanMgr_DmlDhcpcSetReqOptionValues + ( + NULL, + pDhcpc->Cfg.InstanceNumber, + ulIndex, + pReqOption->InstanceNumber, + pReqOption->Alias + ); + + if ( returnStatus != ANSC_STATUS_SUCCESS ) + { + AnscFreeMemory(pReqOption); + AnscFreeMemory(pCxtLink); + break; + } + pCxtLink->InstanceNumber = pReqOption->InstanceNumber; + + /* Put into our list */ + SListPushEntryByInsNum(&pClientCxtLink->ReqOptionList, (PCONTEXT_LINK_OBJECT)pCxtLink); + } + else + { + pCxtLink->InstanceNumber = pReqOption->InstanceNumber; + + /* This case never happen. Add it just for simulation code run well */ + if ( pClientCxtLink->maxInstanceOfReq < pReqOption->InstanceNumber ) + { + pClientCxtLink->maxInstanceOfReq = pReqOption->InstanceNumber; + bNeedSave = TRUE; + } + + /* if this entry is in link tree already because it's delay_added table */ + pCxtLink2 = (PCONTEXT_LINK_OBJECT)SListGetEntryByInsNum(&pClientCxtLink->ReqOptionList, pReqOption->InstanceNumber); + if ( !pCxtLink2 ) + { + SListPushEntryByInsNum(&pClientCxtLink->ReqOptionList, (PCONTEXT_LINK_OBJECT)pCxtLink); + } + else + { + AnscFreeMemory( pCxtLink2->hContext ); + pCxtLink2->hContext = (ANSC_HANDLE)pSendOption; + if ( pCxtLink2->bNew ) + { + pCxtLink2->bNew = FALSE; + bNeedSave = TRUE; + } + + AnscFreeMemory(pCxtLink); + pCxtLink = pCxtLink2; + pCxtLink2 = NULL; + } + + } + } + + /* We begin treat DHCPv4.Client.{i}.SentOption.{i} */ + count = WanMgr_DmlDhcpcGetNumberOfSentOption + ( + NULL, + pDhcpc->Cfg.InstanceNumber + ); + + for ( ulIndex2 = 0; ulIndex2 < count; ulIndex2++ ) + { + pSendOption = (PCOSA_DML_DHCP_OPT)AnscAllocateMemory( sizeof(COSA_DML_DHCP_OPT) ); + if ( !pSendOption ) + { + break; + } + + DHCPV4_SENDOPTION_SET_DEFAULTVALUE(pSendOption); + returnStatus = WanMgr_DmlDhcpcGetSentOption + ( + NULL, + pDhcpc->Cfg.InstanceNumber, + ulIndex2, + pSendOption + ); + if ( returnStatus != ANSC_STATUS_SUCCESS ) + { + AnscFreeMemory(pSendOption); + break; + } + + pCxtLink = (PCONTEXT_LINK_OBJECT)AnscAllocateMemory( sizeof(CONTEXT_LINK_OBJECT) ); + if ( !pCxtLink ) + { + AnscFreeMemory(pSendOption); + break; + } + + CONTEXT_LINK_INITIATION_CONTENT(pCxtLink); + pCxtLink->hContext = (ANSC_HANDLE)pSendOption; + pCxtLink->hParentTable = (ANSC_HANDLE)pClientCxtLink; + pCxtLink->bNew = FALSE; + + if ( !pSendOption->InstanceNumber ) + { + if ( !++pClientCxtLink->maxInstanceOfSend ) + { + pClientCxtLink->maxInstanceOfSend = 1; + bNeedSave = TRUE; + } + bNeedSave = TRUE; + pSendOption->InstanceNumber = pClientCxtLink->maxInstanceOfSend; + + _ansc_sprintf( pSendOption->Alias, "SentOption%lu", pSendOption->InstanceNumber ); + + returnStatus = WanMgr_DmlDhcpcSetSentOptionValues + ( + NULL, + pDhcpc->Cfg.InstanceNumber, + ulIndex, + pSendOption->InstanceNumber, + pSendOption->Alias + ); + + if ( returnStatus != ANSC_STATUS_SUCCESS ) + { + AnscFreeMemory(pSendOption); + AnscFreeMemory(pCxtLink); + break; + } + + pCxtLink->InstanceNumber = pSendOption->InstanceNumber; + + /* Put into our list */ + SListPushEntryByInsNum(&pClientCxtLink->SendOptionList, (PCONTEXT_LINK_OBJECT)pCxtLink); + + } + else + { + pCxtLink->InstanceNumber = pSendOption->InstanceNumber; + + /* This case never happen. Add it just for simulation code run well */ + if ( pClientCxtLink->maxInstanceOfSend < pSendOption->InstanceNumber ) + { + pClientCxtLink->maxInstanceOfSend = pSendOption->InstanceNumber; + } + + /* if this entry is in link tree already because it's delay_added table */ + pCxtLink2 = (PCONTEXT_LINK_OBJECT)SListGetEntryByInsNum(&pClientCxtLink->SendOptionList, pSendOption->InstanceNumber); + if ( !pCxtLink2 ) + { + SListPushEntryByInsNum(&pClientCxtLink->SendOptionList, (PCONTEXT_LINK_OBJECT)pCxtLink); + } + else + { + AnscFreeMemory( pCxtLink2->hContext ); + pCxtLink2->hContext = (ANSC_HANDLE)pSendOption; + if ( pCxtLink2->bNew ) + { + pCxtLink2->bNew = FALSE; + bNeedSave = TRUE; + } + + AnscFreeMemory(pCxtLink); + pCxtLink = pCxtLink2; + pCxtLink2 = NULL; + } + + } + } + } + + /* Max InstanceNumber is changed. Save now.*/ + if (bNeedSave) + { + WanMgr_Dhcpv4RegSetDhcpv4Info(pDhcpv4); + } + + return returnStatus; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ANSC_STATUS + WanMgr_Dhcpv4RegGetDhcpv4Info + ( + ANSC_HANDLE hThisObject + ); + + description: + + This function is called to retrieve backend inform and put them into our trees. + + argument: ANSC_HANDLE hThisObject + This handle is actually the pointer of dhcpv4 + itself. + + return: status of operation. + +**********************************************************************/ + +ANSC_STATUS +WanMgr_Dhcpv4RegGetDhcpv4Info + ( + ANSC_HANDLE hThisObject + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PWAN_DHCPV4_DATA pMyObject = (PWAN_DHCPV4_DATA )hThisObject; + + PPOAM_IREP_FOLDER_OBJECT pPoamIrepFoDhcpv4 = (PPOAM_IREP_FOLDER_OBJECT )pMyObject->hIrepFolderDhcpv4; + PPOAM_IREP_FOLDER_OBJECT pPoamIrepFoClient = (PPOAM_IREP_FOLDER_OBJECT )NULL; + PPOAM_IREP_FOLDER_OBJECT pPoamIrepFoReqOpt = (PPOAM_IREP_FOLDER_OBJECT )NULL; + PPOAM_IREP_FOLDER_OBJECT pPoamIrepFoSndOpt = (PPOAM_IREP_FOLDER_OBJECT )NULL; + PPOAM_IREP_FOLDER_OBJECT pPoamIrepFoEnumClient = (PPOAM_IREP_FOLDER_OBJECT )NULL; + PPOAM_IREP_FOLDER_OBJECT pPoamIrepFoEnumReqOpt = (PPOAM_IREP_FOLDER_OBJECT )NULL; + PPOAM_IREP_FOLDER_OBJECT pPoamIrepFoEnumSndOpt = (PPOAM_IREP_FOLDER_OBJECT )NULL; + + PDHCPC_CONTEXT_LINK_OBJECT pDhcpcContext = NULL; + PCONTEXT_LINK_OBJECT pDhcpcReqOptionContext = NULL; + PCONTEXT_LINK_OBJECT pDhcpcSendOptionContext = NULL; + PSLAP_VARIABLE pSlapVariable = NULL; + ULONG ulEntryCount = 0; + ULONG ulIndex = 0; + ULONG ulEntryCount2 = 0; + ULONG ulIndex2 = 0; + ULONG uInstanceNumber = 0; + BOOL bNew = FALSE; + char* pAliasClient = NULL; + char* pAliasReqOption = NULL; + char* pAliasSendOption = NULL; + char* pFolderName = NULL; + + PDML_DHCPC_FULL pDhcpv4Client = NULL; + PDML_DHCPC_REQ_OPT pDhcpv4ReqOpt = NULL; + PCOSA_DML_DHCP_OPT pDhcpv4SndOpt = NULL; + + if ( !pPoamIrepFoDhcpv4 ) + { + return ANSC_STATUS_FAILURE; + } + + /* This is saved structure for dhcpv4 + ***************************************** + + + xxx + <1> + xxx + false + + xxx + <1> + xxx + true + + + + xxx + <1> + xxx + true + + + + + + xxx + <1> + xxx + true + + xxx + <1> + xxx + true + + + + + + + **************************************************** + */ + + /* Get Folder Client */ + pPoamIrepFoClient = + (PPOAM_IREP_FOLDER_OBJECT)pPoamIrepFoDhcpv4->GetFolder + ( + (ANSC_HANDLE)pPoamIrepFoDhcpv4, + DHCPV4_IREP_FOLDER_NAME_CLIENT + ); + + if ( !pPoamIrepFoClient ) + { + returnStatus = ANSC_STATUS_FAILURE; + goto EXIT1; + } + + /* Get Maximum number */ + if ( TRUE ) + { + pSlapVariable = + (PSLAP_VARIABLE)pPoamIrepFoClient->GetRecord + ( + (ANSC_HANDLE)pPoamIrepFoClient, + COSA_DML_RR_NAME_Dhcpv4NextInsNunmber, + NULL + ); + + if ( pSlapVariable ) + { + pMyObject->maxInstanceOfClient = pSlapVariable->Variant.varUint32; + + SlapFreeVariable(pSlapVariable); + } + } + + /* enumerate client.{i} */ + ulEntryCount = pPoamIrepFoClient->GetFolderCount((ANSC_HANDLE)pPoamIrepFoClient); + for ( ulIndex = 0; ulIndex < ulEntryCount; ulIndex++ ) + { + /* Get i in client.{i} */ + pFolderName = + pPoamIrepFoClient->EnumFolder + ( + (ANSC_HANDLE)pPoamIrepFoClient, + ulIndex + ); + + if ( !pFolderName ) + { + continue; + } + + uInstanceNumber = _ansc_atol(pFolderName); + + if ( uInstanceNumber == 0 ) + { + AnscFreeMemory(pFolderName); + continue; + } + + pPoamIrepFoEnumClient = pPoamIrepFoClient->GetFolder((ANSC_HANDLE)pPoamIrepFoClient, pFolderName); + + AnscFreeMemory(pFolderName); + + if ( !pPoamIrepFoEnumClient ) + { + continue; + } + + /* Get client.{i}.Alias value*/ + if ( TRUE ) + { + pSlapVariable = + (PSLAP_VARIABLE)pPoamIrepFoEnumClient->GetRecord + ( + (ANSC_HANDLE)pPoamIrepFoEnumClient, + COSA_DML_RR_NAME_Dhcpv4Alias, + NULL + ); + + if ( pSlapVariable ) + { + pAliasClient = AnscCloneString(pSlapVariable->Variant.varString); + + SlapFreeVariable(pSlapVariable); + } + } + + /* Get client.{i}.bNew value*/ + if ( TRUE ) + { + pSlapVariable = + (PSLAP_VARIABLE)pPoamIrepFoEnumClient->GetRecord + ( + (ANSC_HANDLE)pPoamIrepFoEnumClient, + COSA_DML_RR_NAME_Dhcpv4bNew, + NULL + ); + + if ( pSlapVariable ) + { + bNew = pSlapVariable->Variant.varBool; + + SlapFreeVariable(pSlapVariable); + } + else + { + bNew = TRUE; + } + } + + /* Create one entry and keep this delay_added entry */ + pDhcpv4Client = (PDML_DHCPC_FULL)AnscAllocateMemory(sizeof(DML_DHCPC_FULL)); + if ( !pDhcpv4Client ) + { + returnStatus = ANSC_STATUS_FAILURE; + goto EXIT2; + } + + /* set some default value firstly */ + DHCPV4_CLIENT_SET_DEFAULTVALUE(pDhcpv4Client); + + /* save alias and instanceNumber */ + pDhcpv4Client->Cfg.InstanceNumber = uInstanceNumber; + AnscCopyString( pDhcpv4Client->Cfg.Alias, pAliasClient ); + + /* Create one link point */ + pDhcpcContext = (PDHCPC_CONTEXT_LINK_OBJECT)AnscAllocateMemory(sizeof(DHCPC_CONTEXT_LINK_OBJECT)); + if ( !pDhcpcContext ) + { + returnStatus = ANSC_STATUS_FAILURE; + goto EXIT3; + } + + DHCPV4_CLIENT_INITIATION_CONTEXT(pDhcpcContext) + + pDhcpcContext->InstanceNumber = uInstanceNumber; + pDhcpcContext->hContext = (ANSC_HANDLE)pDhcpv4Client; + pDhcpv4Client = 0; + pDhcpcContext->bNew = bNew; /* set to true */ + + SListPushEntryByInsNum(&pMyObject->ClientList, (PCONTEXT_LINK_OBJECT)pDhcpcContext); + + /************************************* + * Begin treat client.{i}.reqOption. * + *************************************/ + pPoamIrepFoReqOpt = + (PPOAM_IREP_FOLDER_OBJECT)pPoamIrepFoEnumClient->GetFolder + ( + (ANSC_HANDLE)pPoamIrepFoEnumClient, + DHCPV4_IREP_FOLDER_NAME_REQOPTION + ); + + if ( !pPoamIrepFoReqOpt ) + { + goto SentOption; + } + + /* Get Maximum number */ + if ( TRUE ) + { + pSlapVariable = + (PSLAP_VARIABLE)pPoamIrepFoReqOpt->GetRecord + ( + (ANSC_HANDLE)pPoamIrepFoReqOpt, + COSA_DML_RR_NAME_Dhcpv4NextInsNunmber, + NULL + ); + + if ( pSlapVariable ) + { + pDhcpcContext->maxInstanceOfReq = pSlapVariable->Variant.varUint32; + + SlapFreeVariable(pSlapVariable); + } + } + + /* enumerate client.{i}.reqOption.{i} */ + ulEntryCount2 = pPoamIrepFoReqOpt->GetFolderCount((ANSC_HANDLE)pPoamIrepFoReqOpt); + + for ( ulIndex2 = 0; ulIndex2 < ulEntryCount2; ulIndex2++ ) + { + /* Get i in client.{i}.reqOption.{i} */ + pFolderName = + pPoamIrepFoReqOpt->EnumFolder + ( + (ANSC_HANDLE)pPoamIrepFoReqOpt, + ulIndex2 + ); + + if ( !pFolderName ) + { + continue; + } + + uInstanceNumber = _ansc_atol(pFolderName); + + if ( uInstanceNumber == 0 ) + { + AnscFreeMemory(pFolderName); /* tom*/ + continue; + } + + pPoamIrepFoEnumReqOpt = pPoamIrepFoReqOpt->GetFolder((ANSC_HANDLE)pPoamIrepFoReqOpt, pFolderName); + + AnscFreeMemory(pFolderName); + + if ( !pPoamIrepFoEnumReqOpt ) + { + continue; + } + + /* Get client.{i}.reqOption.{i}.Alias value*/ + if ( TRUE ) + { + pSlapVariable = + (PSLAP_VARIABLE)pPoamIrepFoEnumReqOpt->GetRecord + ( + (ANSC_HANDLE)pPoamIrepFoEnumReqOpt, + COSA_DML_RR_NAME_Dhcpv4Alias, + NULL + ); + + if ( pSlapVariable ) + { + pAliasReqOption= AnscCloneString(pSlapVariable->Variant.varString); + + SlapFreeVariable(pSlapVariable); + } + } + + /* Get client.{i}.reqOption.{i}.bNew value*/ + if ( TRUE ) + { + pSlapVariable = + (PSLAP_VARIABLE)pPoamIrepFoEnumReqOpt->GetRecord + ( + (ANSC_HANDLE)pPoamIrepFoEnumReqOpt, + COSA_DML_RR_NAME_Dhcpv4bNew, + NULL + ); + + if ( pSlapVariable ) + { + bNew = pSlapVariable->Variant.varBool; + + SlapFreeVariable(pSlapVariable); + } + else + { + bNew = TRUE; + } + } + + + /* Create one link and ask backend to get content */ + pDhcpv4ReqOpt = (PDML_DHCPC_REQ_OPT)AnscAllocateMemory(sizeof(DML_DHCPC_REQ_OPT)); + if ( !pDhcpv4ReqOpt ) + { + returnStatus = ANSC_STATUS_FAILURE; + goto EXIT3; + } + + /* set some default value firstly */ + DHCPV4_REQOPTION_SET_DEFAULTVALUE(pDhcpv4ReqOpt); + + /* save alias and instanceNumber */ + pDhcpv4ReqOpt->InstanceNumber = uInstanceNumber; + AnscCopyString( pDhcpv4ReqOpt->Alias, pAliasReqOption ); + + /* Create one link */ + pDhcpcReqOptionContext = (PCONTEXT_LINK_OBJECT)AnscAllocateMemory(sizeof(CONTEXT_LINK_OBJECT)); + if ( !pDhcpcReqOptionContext ) + { + returnStatus = ANSC_STATUS_FAILURE; + AnscFreeMemory( pDhcpv4ReqOpt ); /*RDKB-6735, CID-33487, free unused resource before exit*/ + pDhcpv4ReqOpt = NULL; + goto EXIT2; + } + + CONTEXT_LINK_INITIATION_CONTENT(pDhcpcReqOptionContext); + + pDhcpcReqOptionContext->InstanceNumber = uInstanceNumber; + pDhcpcReqOptionContext->hContext = (ANSC_HANDLE)pDhcpv4ReqOpt; + pDhcpv4ReqOpt = NULL; + pDhcpcReqOptionContext->hParentTable = (ANSC_HANDLE)pDhcpcContext; + pDhcpcReqOptionContext->bNew = bNew; + + SListPushEntryByInsNum(&pDhcpcContext->ReqOptionList, (PCONTEXT_LINK_OBJECT)pDhcpcReqOptionContext); + + /* release some memory */ + if (pAliasReqOption) + { + AnscFreeMemory(pAliasReqOption); + pAliasReqOption = NULL; + } + + pPoamIrepFoEnumReqOpt->Remove((ANSC_HANDLE)pPoamIrepFoEnumReqOpt); + pPoamIrepFoEnumReqOpt = NULL; + } + + pPoamIrepFoReqOpt->Remove((ANSC_HANDLE)pPoamIrepFoReqOpt); + pPoamIrepFoReqOpt = NULL; + +SentOption: + /* + Begin treat client.{i}.sentOption. + */ + pPoamIrepFoSndOpt = + (PPOAM_IREP_FOLDER_OBJECT)pPoamIrepFoEnumClient->GetFolder + ( + (ANSC_HANDLE)pPoamIrepFoEnumClient, + DHCPV4_IREP_FOLDER_NAME_SENTOPTION + ); + + if ( !pPoamIrepFoSndOpt ) + { + goto ClientEnd; + } + + /* Get Maximum number */ + if ( TRUE ) + { + pSlapVariable = + (PSLAP_VARIABLE)pPoamIrepFoSndOpt->GetRecord + ( + (ANSC_HANDLE)pPoamIrepFoSndOpt, + COSA_DML_RR_NAME_Dhcpv4NextInsNunmber, + NULL + ); + + if ( pSlapVariable ) + { + pDhcpcContext->maxInstanceOfSend = pSlapVariable->Variant.varUint32; + + SlapFreeVariable(pSlapVariable); + } + } + + /* enumerate client.{i}.sentOption.{i} */ + ulEntryCount2 = pPoamIrepFoSndOpt->GetFolderCount((ANSC_HANDLE)pPoamIrepFoSndOpt); + + for ( ulIndex2 = 0; ulIndex2 < ulEntryCount2; ulIndex2++ ) + { + /* Get i in client.{i}.sentOption.{i} */ + pFolderName = + pPoamIrepFoSndOpt->EnumFolder + ( + (ANSC_HANDLE)pPoamIrepFoSndOpt, + ulIndex2 + ); + + if ( !pFolderName ) + { + continue; + } + + uInstanceNumber = _ansc_atol(pFolderName); + + if ( uInstanceNumber == 0 ) + { + AnscFreeMemory(pFolderName); /* tom*/ + continue; + } + + pPoamIrepFoEnumSndOpt = pPoamIrepFoSndOpt->GetFolder((ANSC_HANDLE)pPoamIrepFoSndOpt, pFolderName); + + AnscFreeMemory(pFolderName); + + if ( !pPoamIrepFoEnumSndOpt ) + { + continue; + } + + /* Get client.{i}.sentOption.{i}.Alias value*/ + if ( TRUE ) + { + pSlapVariable = + (PSLAP_VARIABLE)pPoamIrepFoEnumSndOpt->GetRecord + ( + (ANSC_HANDLE)pPoamIrepFoEnumSndOpt, + COSA_DML_RR_NAME_Dhcpv4Alias, + NULL + ); + + if ( pSlapVariable ) + { + pAliasSendOption = AnscCloneString(pSlapVariable->Variant.varString); + + SlapFreeVariable(pSlapVariable); + } + } + + /* Get client.{i}.sentOption.{i}.bNew value*/ + if ( TRUE ) + { + pSlapVariable = + (PSLAP_VARIABLE)pPoamIrepFoEnumSndOpt->GetRecord + ( + (ANSC_HANDLE)pPoamIrepFoEnumSndOpt, + COSA_DML_RR_NAME_Dhcpv4bNew, + NULL + ); + + if ( pSlapVariable ) + { + bNew = pSlapVariable->Variant.varBool; + + SlapFreeVariable(pSlapVariable); + } + else + { + bNew = TRUE; + } + } + + /* Create one link and ask backend to get content */ + pDhcpv4SndOpt = (PCOSA_DML_DHCP_OPT)AnscAllocateMemory(sizeof(COSA_DML_DHCP_OPT)); + if ( !pDhcpv4SndOpt ) + { + returnStatus = ANSC_STATUS_FAILURE; + goto EXIT3; + } + + /* set some default value firstly */ + DHCPV4_SENDOPTION_SET_DEFAULTVALUE(pDhcpv4SndOpt); + + /* save alias and instanceNumber */ + pDhcpv4SndOpt->InstanceNumber = uInstanceNumber; + AnscCopyString( pDhcpv4SndOpt->Alias, pAliasSendOption ); + + pDhcpcSendOptionContext = (PCONTEXT_LINK_OBJECT)AnscAllocateMemory(sizeof(CONTEXT_LINK_OBJECT)); + if ( !pDhcpcSendOptionContext ) + { + AnscFreeMemory(pDhcpv4SndOpt); /*RDKB-6735, CID-33261, free unused resource before exit*/ + pDhcpv4SndOpt = NULL; + returnStatus = ANSC_STATUS_FAILURE; + goto EXIT2; + } + + CONTEXT_LINK_INITIATION_CONTENT(pDhcpcSendOptionContext); + + pDhcpcSendOptionContext->InstanceNumber = uInstanceNumber; + pDhcpcSendOptionContext->hContext = (ANSC_HANDLE)pDhcpv4SndOpt; + pDhcpv4SndOpt = NULL; + pDhcpcSendOptionContext->hParentTable = pDhcpcContext; + pDhcpcSendOptionContext->bNew = bNew; + + SListPushEntryByInsNum(&pDhcpcContext->SendOptionList, (PCONTEXT_LINK_OBJECT)pDhcpcSendOptionContext); + + /* release some memory */ + + if (pAliasSendOption) + { + AnscFreeMemory(pAliasSendOption); + pAliasSendOption = NULL; + } + + pPoamIrepFoEnumSndOpt->Remove((ANSC_HANDLE)pPoamIrepFoEnumSndOpt); + pPoamIrepFoEnumSndOpt = NULL; + } + + pPoamIrepFoSndOpt->Remove((ANSC_HANDLE)pPoamIrepFoSndOpt); + pPoamIrepFoSndOpt = NULL; + +ClientEnd: + + /* release some memory */ + if (pAliasClient) + { + AnscFreeMemory(pAliasClient); + pAliasClient = NULL; + } + + pPoamIrepFoEnumClient->Remove((ANSC_HANDLE)pPoamIrepFoEnumClient); + pPoamIrepFoEnumClient = NULL; + } + + pPoamIrepFoClient->Remove((ANSC_HANDLE)pPoamIrepFoClient); + pPoamIrepFoClient = NULL; + + +EXIT3: + if(pDhcpv4Client) + AnscFreeMemory(pDhcpv4Client); + + if(pDhcpv4ReqOpt ) + AnscFreeMemory(pDhcpv4ReqOpt); + + if(pDhcpv4SndOpt ) + AnscFreeMemory(pDhcpv4SndOpt); + +EXIT2: + + if(pAliasReqOption) + AnscFreeMemory(pAliasReqOption); + + if(pAliasSendOption) + AnscFreeMemory(pAliasSendOption); + + if(pAliasClient) + AnscFreeMemory(pAliasClient); + +EXIT1: + + if ( pPoamIrepFoClient ) + pPoamIrepFoClient->Remove((ANSC_HANDLE)pPoamIrepFoClient); + + if ( pPoamIrepFoEnumClient ) + pPoamIrepFoEnumClient->Remove((ANSC_HANDLE)pPoamIrepFoEnumClient); + + if ( pPoamIrepFoReqOpt) + pPoamIrepFoReqOpt->Remove((ANSC_HANDLE)pPoamIrepFoReqOpt); + + if ( pPoamIrepFoEnumReqOpt ) + pPoamIrepFoEnumReqOpt->Remove((ANSC_HANDLE)pPoamIrepFoEnumReqOpt); + + if ( pPoamIrepFoSndOpt) + pPoamIrepFoSndOpt->Remove((ANSC_HANDLE)pPoamIrepFoSndOpt); + + if ( pPoamIrepFoEnumSndOpt) + pPoamIrepFoEnumSndOpt->Remove((ANSC_HANDLE)pPoamIrepFoEnumSndOpt); + + return returnStatus; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ANSC_STATUS + WanMgr_Dhcpv4RegSetDhcpv4Info + ( + ANSC_HANDLE hThisObject + ); + + description: + + This function is called to save current NextInstanceNumber and Delay_added + entry into sysregistry. + + argument: ANSC_HANDLE hThisObject + This handle is actually the pointer of dhcpv4 + itself. + + return: status of operation. + +**********************************************************************/ + +ANSC_STATUS WanMgr_Dhcpv4RegSetDhcpv4Info ( ANSC_HANDLE hThisObject ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PWAN_DHCPV4_DATA pMyObject = (PWAN_DHCPV4_DATA )hThisObject; + + PPOAM_IREP_FOLDER_OBJECT pPoamIrepFoDhcpv4 = (PPOAM_IREP_FOLDER_OBJECT )pMyObject->hIrepFolderDhcpv4; + PPOAM_IREP_FOLDER_OBJECT pPoamIrepFoClient = (PPOAM_IREP_FOLDER_OBJECT )NULL; + PPOAM_IREP_FOLDER_OBJECT pPoamIrepFoReqOpt = (PPOAM_IREP_FOLDER_OBJECT )NULL; + PPOAM_IREP_FOLDER_OBJECT pPoamIrepFoSndOpt = (PPOAM_IREP_FOLDER_OBJECT )NULL; + PPOAM_IREP_FOLDER_OBJECT pPoamIrepFoEnumClient = (PPOAM_IREP_FOLDER_OBJECT )NULL; + PPOAM_IREP_FOLDER_OBJECT pPoamIrepFoEnumReqOpt = (PPOAM_IREP_FOLDER_OBJECT )NULL; + PPOAM_IREP_FOLDER_OBJECT pPoamIrepFoEnumSndOpt = (PPOAM_IREP_FOLDER_OBJECT )NULL; + + PSINGLE_LINK_ENTRY pSLinkEntry = (PSINGLE_LINK_ENTRY )NULL; + PSINGLE_LINK_ENTRY pSLinkEntry2 = (PSINGLE_LINK_ENTRY )NULL; + PDHCPC_CONTEXT_LINK_OBJECT pDhcpcContext = NULL; + PCONTEXT_LINK_OBJECT pDhcpcReqOptionContext = NULL; + PCONTEXT_LINK_OBJECT pDhcpcSendOptionContext = NULL; + PSLAP_VARIABLE pSlapVariable = NULL; + ULONG ulEntryCount = 0; + ULONG ulIndex = 0; + ULONG ulEntryCount2 = 0; + ULONG ulIndex2 = 0; + ULONG uInstanceNumber = 0; + char* pAliasClient = NULL; + char* pAliasReqOption = NULL; + char* pAliasSendOption = NULL; + char* pFolderName = NULL; + char FolderName[16] = {0}; + + PDML_DHCPC_FULL pDhcpv4Client = NULL; + PDML_DHCPC_REQ_OPT pDhcpv4ReqOpt = NULL; + PCOSA_DML_DHCP_OPT pDhcpv4SndOpt = NULL; + + if ( !pPoamIrepFoDhcpv4 ) + { + return ANSC_STATUS_FAILURE; + } + else + { + pPoamIrepFoDhcpv4->EnableFileSync((ANSC_HANDLE)pPoamIrepFoDhcpv4, FALSE); + } + + if ( TRUE ) + { + pPoamIrepFoDhcpv4->Clear((ANSC_HANDLE)pPoamIrepFoDhcpv4); + + SlapAllocVariable(pSlapVariable); + + if ( !pSlapVariable ) + { + returnStatus = ANSC_STATUS_RESOURCES; + + goto EXIT1; + } + } + + /* This is saved structure for dhcpv4 + ***************************************** + + + xxx + <1> + xxx + false + + xxx + <1> + xxx + false + + + + xxx + <1> + xxx + true + + + + + + xxx + <1> + xxx + true + + xxx + <1> + xxx + true + + + + + + + **************************************************** + */ + + /* Add dhcpv4.client.*/ + pPoamIrepFoClient = + pPoamIrepFoDhcpv4->AddFolder + ( + (ANSC_HANDLE)pPoamIrepFoDhcpv4, + DHCPV4_IREP_FOLDER_NAME_CLIENT, + 0 + ); + + if ( !pPoamIrepFoClient ) + { + goto EXIT1; + } + + /* add client.{i}.maxInstanceNumber */ + if ( TRUE ) + { + pSlapVariable->Syntax = SLAP_VAR_SYNTAX_uint32; + pSlapVariable->Variant.varUint32 = pMyObject->maxInstanceOfClient; + + returnStatus = + pPoamIrepFoClient->AddRecord + ( + (ANSC_HANDLE)pPoamIrepFoClient, + COSA_DML_RR_NAME_Dhcpv4NextInsNunmber, + SYS_REP_RECORD_TYPE_UINT, + SYS_RECORD_CONTENT_DEFAULT, + pSlapVariable, + 0 + ); + + SlapCleanVariable(pSlapVariable); + SlapInitVariable (pSlapVariable); + } + + pSLinkEntry = AnscSListGetFirstEntry(&pMyObject->ClientList); + + while ( pSLinkEntry ) + { + /* create dhcpv4.client.{i} */ + + pDhcpcContext = ACCESS_CONTEXT_DHCPC_LINK_OBJECT(pSLinkEntry); + pSLinkEntry = AnscSListGetNextEntry(pSLinkEntry); + + pDhcpv4Client = (PDML_DHCPC_FULL)pDhcpcContext->hContext; + + /* When this entry has been added to backend, has not any child and maxInstanceNumber is 0 + We need not save this entry */ + if ( !pDhcpcContext->bNew && + !AnscSListQueryDepth(&pDhcpcContext->ReqOptionList ) && + !AnscSListQueryDepth(&pDhcpcContext->SendOptionList ) && + pDhcpcContext->maxInstanceOfSend == 0 && + pDhcpcContext->maxInstanceOfReq == 0 + ) + { + continue; + } + + _ansc_sprintf(FolderName, "%lu", pDhcpcContext->InstanceNumber); + + pPoamIrepFoEnumClient = + pPoamIrepFoClient->AddFolder + ( + (ANSC_HANDLE)pPoamIrepFoClient, + FolderName, + 0 + ); + + if ( !pPoamIrepFoEnumClient ) + { + continue; + } + + /* add dhcpv4.client.{i}.alias */ + if ( TRUE ) + { + pSlapVariable->Syntax = SLAP_VAR_SYNTAX_string; + pSlapVariable->Variant.varString = AnscCloneString(pDhcpv4Client->Cfg.Alias); + + returnStatus = + pPoamIrepFoEnumClient->AddRecord + ( + (ANSC_HANDLE)pPoamIrepFoEnumClient, + COSA_DML_RR_NAME_Dhcpv4Alias, + SYS_REP_RECORD_TYPE_ASTR, + SYS_RECORD_CONTENT_DEFAULT, + pSlapVariable, + 0 + ); + + SlapCleanVariable(pSlapVariable); + SlapInitVariable (pSlapVariable); + } + + /* add dhcpv4.client.{i}.bNew */ + if ( TRUE ) + { + pSlapVariable->Syntax = SLAP_VAR_SYNTAX_bool; + pSlapVariable->Variant.varBool = pDhcpcContext->bNew; + + returnStatus = + pPoamIrepFoEnumClient->AddRecord + ( + (ANSC_HANDLE)pPoamIrepFoEnumClient, + COSA_DML_RR_NAME_Dhcpv4bNew, + SYS_REP_RECORD_TYPE_BOOL, + SYS_RECORD_CONTENT_DEFAULT, + pSlapVariable, + 0 + ); + + SlapCleanVariable(pSlapVariable); + SlapInitVariable (pSlapVariable); + } + + /* + begin add reqOption + */ + + if ( !AnscSListQueryDepth(&pDhcpcContext->ReqOptionList) ) + { + goto SentOption; + } + + /* Add dhcpv4.client.{i}.reqOption */ + pPoamIrepFoReqOpt = + pPoamIrepFoEnumClient->AddFolder + ( + (ANSC_HANDLE)pPoamIrepFoEnumClient, + DHCPV4_IREP_FOLDER_NAME_REQOPTION, + 0 + ); + + if ( !pPoamIrepFoReqOpt ) + { + goto EXIT1; + } + + /* add client.{i}.reqOption.maxInstanceNumber */ + if ( TRUE ) + { + pSlapVariable->Syntax = SLAP_VAR_SYNTAX_uint32; + pSlapVariable->Variant.varUint32 = pDhcpcContext->maxInstanceOfReq; + + returnStatus = + pPoamIrepFoReqOpt->AddRecord + ( + (ANSC_HANDLE)pPoamIrepFoReqOpt, + COSA_DML_RR_NAME_Dhcpv4NextInsNunmber, + SYS_REP_RECORD_TYPE_UINT, + SYS_RECORD_CONTENT_DEFAULT, + pSlapVariable, + 0 + ); + + SlapCleanVariable(pSlapVariable); + SlapInitVariable (pSlapVariable); + } + + pSLinkEntry2 = AnscSListGetFirstEntry(&pDhcpcContext->ReqOptionList); + + while ( pSLinkEntry2 ) + { + /* create dhcpv4.client.{i}.reqOption.{i} */ + + pDhcpcReqOptionContext = ACCESS_CONTEXT_LINK_OBJECT(pSLinkEntry2); + pSLinkEntry2 = AnscSListGetNextEntry(pSLinkEntry2); + + pDhcpv4ReqOpt= (PDML_DHCPC_REQ_OPT)pDhcpcReqOptionContext->hContext; + + if ( !pDhcpcReqOptionContext->bNew ) + { + continue; + } + + _ansc_sprintf(FolderName, "%lu", pDhcpcReqOptionContext->InstanceNumber); + + pPoamIrepFoEnumReqOpt = + pPoamIrepFoReqOpt->AddFolder + ( + (ANSC_HANDLE)pPoamIrepFoReqOpt, + FolderName, + 0 + ); + + if ( !pPoamIrepFoEnumReqOpt ) + { + continue; + } + + /* create dhcpv4.client.{i}.reqOption.{i}.alias */ + if ( TRUE ) + { + pSlapVariable->Syntax = SLAP_VAR_SYNTAX_string; + pSlapVariable->Variant.varString = AnscCloneString(pDhcpv4ReqOpt->Alias); + + returnStatus = + pPoamIrepFoEnumReqOpt->AddRecord + ( + (ANSC_HANDLE)pPoamIrepFoEnumReqOpt, + COSA_DML_RR_NAME_Dhcpv4Alias, + SYS_REP_RECORD_TYPE_ASTR, + SYS_RECORD_CONTENT_DEFAULT, + pSlapVariable, + 0 + ); + + SlapCleanVariable(pSlapVariable); + SlapInitVariable (pSlapVariable); + } + + /* create dhcpv4.client.{i}.reqOption.{i}.alias */ + if ( TRUE ) + { + pSlapVariable->Syntax = SLAP_VAR_SYNTAX_bool; + pSlapVariable->Variant.varBool = pDhcpcReqOptionContext->bNew; + + returnStatus = + pPoamIrepFoEnumReqOpt->AddRecord + ( + (ANSC_HANDLE)pPoamIrepFoEnumReqOpt, + COSA_DML_RR_NAME_Dhcpv4bNew, + SYS_REP_RECORD_TYPE_BOOL, + SYS_RECORD_CONTENT_DEFAULT, + pSlapVariable, + 0 + ); + + SlapCleanVariable(pSlapVariable); + SlapInitVariable (pSlapVariable); + } + + pPoamIrepFoEnumReqOpt->Remove((ANSC_HANDLE)pPoamIrepFoEnumReqOpt); + pPoamIrepFoEnumReqOpt = NULL; + } + + pPoamIrepFoReqOpt->Remove((ANSC_HANDLE)pPoamIrepFoReqOpt); + pPoamIrepFoReqOpt = NULL; + + /* + begin add sendOption + */ +SentOption: + + if ( !AnscSListQueryDepth(&pDhcpcContext->SendOptionList) ) + { + goto ClientEnd; + } + + /* Add dhcpv4.client.{i}.sendOption */ + pPoamIrepFoSndOpt = + pPoamIrepFoEnumClient->AddFolder + ( + (ANSC_HANDLE)pPoamIrepFoEnumClient, + DHCPV4_IREP_FOLDER_NAME_SENTOPTION, + 0 + ); + + if ( !pPoamIrepFoSndOpt ) + { + goto EXIT1; + } + + /* add client.{i}.sendOption.maxInstanceNumber */ + if ( TRUE ) + { + pSlapVariable->Syntax = SLAP_VAR_SYNTAX_uint32; + pSlapVariable->Variant.varUint32 = pDhcpcContext->maxInstanceOfSend; + + returnStatus = + pPoamIrepFoSndOpt->AddRecord + ( + (ANSC_HANDLE)pPoamIrepFoSndOpt, + COSA_DML_RR_NAME_Dhcpv4NextInsNunmber, + SYS_REP_RECORD_TYPE_UINT, + SYS_RECORD_CONTENT_DEFAULT, + pSlapVariable, + 0 + ); + + SlapCleanVariable(pSlapVariable); + SlapInitVariable (pSlapVariable); + } + + pSLinkEntry2 = AnscSListGetFirstEntry(&pDhcpcContext->SendOptionList); + + while ( pSLinkEntry2 ) + { + /* create dhcpv4.client.{i}.sendOption.{i} */ + + pDhcpcSendOptionContext = ACCESS_CONTEXT_LINK_OBJECT(pSLinkEntry2); + pSLinkEntry2 = AnscSListGetNextEntry(pSLinkEntry2); + + pDhcpv4SndOpt= (PCOSA_DML_DHCP_OPT)pDhcpcSendOptionContext->hContext; + + if ( !pDhcpcSendOptionContext->bNew ) + { + continue; + } + + _ansc_sprintf(FolderName, "%lu", pDhcpcSendOptionContext->InstanceNumber); + + pPoamIrepFoEnumSndOpt = + pPoamIrepFoSndOpt->AddFolder + ( + (ANSC_HANDLE)pPoamIrepFoSndOpt, + FolderName, + 0 + ); + + if ( !pPoamIrepFoEnumSndOpt ) + { + continue; + } + + /* create dhcpv4.client.{i}.sendOption.{i}.alias */ + if ( TRUE ) + { + pSlapVariable->Syntax = SLAP_VAR_SYNTAX_string; + pSlapVariable->Variant.varString = AnscCloneString(pDhcpv4SndOpt->Alias); + + returnStatus = + pPoamIrepFoEnumSndOpt->AddRecord + ( + (ANSC_HANDLE)pPoamIrepFoEnumSndOpt, + COSA_DML_RR_NAME_Dhcpv4Alias, + SYS_REP_RECORD_TYPE_ASTR, + SYS_RECORD_CONTENT_DEFAULT, + pSlapVariable, + 0 + ); + + SlapCleanVariable(pSlapVariable); + SlapInitVariable (pSlapVariable); + } + + /* create dhcpv4.client.{i}.sendOption.{i}.bNew */ + if ( TRUE ) + { + pSlapVariable->Syntax = SLAP_VAR_SYNTAX_bool; + pSlapVariable->Variant.varBool = pDhcpcSendOptionContext->bNew; + + returnStatus = + pPoamIrepFoEnumSndOpt->AddRecord + ( + (ANSC_HANDLE)pPoamIrepFoEnumSndOpt, + COSA_DML_RR_NAME_Dhcpv4bNew, + SYS_REP_RECORD_TYPE_BOOL, + SYS_RECORD_CONTENT_DEFAULT, + pSlapVariable, + 0 + ); + + SlapCleanVariable(pSlapVariable); + SlapInitVariable (pSlapVariable); + } + + pPoamIrepFoEnumSndOpt->Remove((ANSC_HANDLE)pPoamIrepFoEnumSndOpt); + pPoamIrepFoEnumSndOpt = NULL; + } + + pPoamIrepFoSndOpt->Remove((ANSC_HANDLE)pPoamIrepFoSndOpt); + pPoamIrepFoSndOpt = NULL; + +ClientEnd: + + /*release some resource */ + pPoamIrepFoEnumClient->Remove((ANSC_HANDLE)pPoamIrepFoEnumClient); + pPoamIrepFoEnumClient = NULL; + } + + pPoamIrepFoClient->Remove((ANSC_HANDLE)pPoamIrepFoClient); + pPoamIrepFoClient = NULL; + +EXIT1: + if ( pSlapVariable ) + { + SlapFreeVariable(pSlapVariable); + pSlapVariable = NULL; + } + + if ( pPoamIrepFoClient ) + pPoamIrepFoClient->Remove((ANSC_HANDLE)pPoamIrepFoClient); + + if ( pPoamIrepFoEnumClient ) + pPoamIrepFoEnumClient->Remove((ANSC_HANDLE)pPoamIrepFoEnumClient); + + if ( pPoamIrepFoReqOpt) + pPoamIrepFoReqOpt->Remove((ANSC_HANDLE)pPoamIrepFoReqOpt); + + if ( pPoamIrepFoEnumReqOpt ) + pPoamIrepFoEnumReqOpt->Remove((ANSC_HANDLE)pPoamIrepFoEnumReqOpt); + + if ( pPoamIrepFoSndOpt) + pPoamIrepFoSndOpt->Remove((ANSC_HANDLE)pPoamIrepFoSndOpt); + + if ( pPoamIrepFoEnumSndOpt) + pPoamIrepFoEnumSndOpt->Remove((ANSC_HANDLE)pPoamIrepFoEnumSndOpt); + + pPoamIrepFoDhcpv4->EnableFileSync((ANSC_HANDLE)pPoamIrepFoDhcpv4, TRUE); + + return returnStatus; +} + + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + WanMgr_Dhcpv4ClientHasDelayAddedChild + ( + PDHCPC_CONTEXT_LINK_OBJECT hContext + ); + + description: + + This function is called to check whether this is child is pending added. If yes, + return TRUE. Or else return FALSE. + + argument: PDHCPC_CONTEXT_LINK_OBJECT hThisObject + This handle is actually the pointer of one context link point. + + return: TRUE or FALSE. + +**********************************************************************/ +BOOL WanMgr_Dhcpv4ClientHasDelayAddedChild ( PDHCPC_CONTEXT_LINK_OBJECT hContext ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PDHCPC_CONTEXT_LINK_OBJECT pDhcpcContext = hContext; + + PSINGLE_LINK_ENTRY pSLinkEntry = (PSINGLE_LINK_ENTRY )NULL; + PCONTEXT_LINK_OBJECT pCxtLink = NULL; + + pSLinkEntry = AnscSListGetFirstEntry(&pDhcpcContext->ReqOptionList); + while ( pSLinkEntry ) + { + pCxtLink = ACCESS_CONTEXT_LINK_OBJECT(pSLinkEntry); + pSLinkEntry = AnscSListGetNextEntry(pSLinkEntry); + + if ( pCxtLink->bNew ) + { + return TRUE; + } + + } + + pSLinkEntry = AnscSListGetFirstEntry(&pDhcpcContext->SendOptionList); + while ( pSLinkEntry ) + { + pCxtLink = ACCESS_CONTEXT_LINK_OBJECT(pSLinkEntry); + pSLinkEntry = AnscSListGetNextEntry(pSLinkEntry); + + if ( pCxtLink->bNew ) + { + return TRUE; + } + + } + + return FALSE; +} + +BOOL +WanMgr_DmlSetIpaddr + ( + PULONG pIPAddr, + PCHAR pString, + ULONG MaxNumber + ) +{ + CHAR *pTmpString = pString; + ULONG i = 0; + ULONG j = 0; + ULONG n = 0; + BOOL bReturn = TRUE; + ULONG pIPAddr2[DML_DHCP_MAX_ENTRIES] = {0}; + + if ( !pIPAddr || !pString || !MaxNumber ) + return FALSE; + + while( pTmpString[i] ) + { + if ( pTmpString[i] == ',' ) + { + pTmpString[i] = 0; + pIPAddr2[n] = _ansc_inet_addr(&pTmpString[j]); + if (pIPAddr2[n] == INADDR_NONE) + { + pTmpString[i] = ','; + + pIPAddr2[n] = 0; + n = MaxNumber; + bReturn = FALSE; + goto EXIT; + } + + pTmpString[i] = ','; + j = i + 1; + n++; + + if ( n >= MaxNumber ) + { + break; + } + } + i++; + } + + /* The last one */ + if ( ( n < MaxNumber ) && ( (i-j) >= 7 ) ) + { + pIPAddr2[n] = _ansc_inet_addr(&pTmpString[j]); + if (pIPAddr2[n] == INADDR_NONE) + { + pIPAddr2[n] = 0; + bReturn = FALSE; + goto EXIT; + } + } + else if ( (i-j) > 1 ) + { + /*This case means there a illegal length ip address.*/ + bReturn = FALSE; + goto EXIT; + } + + /*The setting may be NULL. So this also may clear backend. */ + for(n=0; n < MaxNumber; n++){ + pIPAddr[n] = pIPAddr2[n]; + } + +EXIT: + return bReturn; +} + +BOOL +WanMgr_DmlGetIpaddrString + ( + PUCHAR pString, + PULONG pulStrLength, + PULONG pIPAddr, + ULONG MaxNumber + ) +{ + UCHAR *pTmpString = pString; + ULONG n = 0; + PULONG pIPAddr2 = pIPAddr; + + if ( !pString || !pulStrLength || !pIPAddr || !MaxNumber ) + return FALSE; + + while( pIPAddr2[n] && ( n < MaxNumber ) && ( (*pulStrLength- (pTmpString - pString)) > 15 ) ) + { + AnscCopyString((char *)pTmpString, _ansc_inet_ntoa( *((struct in_addr*)&(pIPAddr2[n]))) ); + + pTmpString[AnscSizeOfString((const char *)pTmpString)] = ','; + + pTmpString = &pTmpString[AnscSizeOfString((const char *)pTmpString)]; + + n++; + } + + if ( pTmpString != pString ) + { + pTmpString[AnscSizeOfString((const char *)pTmpString) -1] = 0; + } + + if ( (*pulStrLength - (pTmpString - pString)) <= 15 ) + { + *pulStrLength = MaxNumber * 16 + 1; + + return FALSE; + } + + return TRUE; +} + + diff --git a/source/WanManager/wanmgr_dhcpv4_internal.h b/source/WanManager/wanmgr_dhcpv4_internal.h new file mode 100644 index 00000000..708fddfe --- /dev/null +++ b/source/WanManager/wanmgr_dhcpv4_internal.h @@ -0,0 +1,220 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2015 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +/********************************************************************** + Copyright [2014] [Cisco Systems, Inc.] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +**********************************************************************/ + +#ifndef _DHCPV4_INTERNAL_H +#define _DHCPV4_INTERNAL_H + +#include "wanmgr_apis.h" + +/* + * This is cosa middle layer definition + * + */ +#define DHCPV4_IREP_FOLDER_NAME "Dhcpv4" +#define DHCPV4_IREP_FOLDER_NAME_CLIENT "Client" +#define DHCPV4_IREP_FOLDER_NAME_REQOPTION "ReqOption" +#define DHCPV4_IREP_FOLDER_NAME_SENTOPTION "SentOption" +#define COSA_DML_RR_NAME_Dhcpv4Alias "Alias" +#define COSA_DML_RR_NAME_Dhcpv4bNew "bNew" +#define COSA_DML_RR_NAME_Dhcpv4NextInsNunmber "NextInstanceNumber" + +#define COSA_DML_DHCPV4_ALIAS 64 + +/* +* This struct is only for dhcpc because it have two sub tables. +* For the two table, they just use common link struct because they havenot sub tables. +*/ +#define COSA_CONTEXT_DHCPC_LINK_CLASS_CONTENT \ + CONTEXT_LINK_CLASS_CONTENT \ + SLIST_HEADER SendOptionList; \ + SLIST_HEADER ReqOptionList; \ + ULONG maxInstanceOfSend; \ + ULONG maxInstanceOfReq; \ + CHAR AliasOfReq[COSA_DML_DHCPV4_ALIAS]; \ + CHAR AliasOfSend[COSA_DML_DHCPV4_ALIAS]; \ + +typedef struct +_DHCPC_CONTEXT_LINK_OBJECT +{ + COSA_CONTEXT_DHCPC_LINK_CLASS_CONTENT +} +DHCPC_CONTEXT_LINK_OBJECT, *PDHCPC_CONTEXT_LINK_OBJECT; + +#define ACCESS_CONTEXT_DHCPC_LINK_OBJECT(p) \ + ACCESS_CONTAINER(p, DHCPC_CONTEXT_LINK_OBJECT, Linkage) \ + +/* +* This struct is for dhcp. +*/ +#define WAN_DHCPV4_DATA_CLASS_CONTENT \ + /* duplication of the base object class content */ \ + BASE_CONTENT \ + /* start of NAT object class content */ \ + SLIST_HEADER X_CISCO_COM_StaticAddressList; \ + SLIST_HEADER ClientList; /* This is for entry added */ \ + ULONG maxInstanceOfClient; \ + CHAR AliasOfClient[COSA_DML_DHCPV4_ALIAS]; \ + ANSC_HANDLE hIrepFolderDhcpv4; \ + +typedef struct +_WAN_DHCPV4_DATA +{ + WAN_DHCPV4_DATA_CLASS_CONTENT +} +WAN_DHCPV4_DATA, *PWAN_DHCPV4_DATA; + + +#define DHCPV4_CLIENT_ENTRY_MATCH(src,dst) \ + (AnscEqualString((src)->Alias, (dst)->Alias, TRUE)) \ + +#define DHCPV4_CLIENT_ENTRY_MATCH2(src,dst) \ + (AnscEqualString((src), (dst), TRUE)) \ + +#define DHCPV4_SENDOPTION_ENTRY_MATCH(src,dst) \ + (AnscEqualString((src)->Alias, (dst)->Alias, TRUE)) \ + +#define DHCPV4_SENDOPTION_ENTRY_MATCH2(src,dst) \ + (AnscEqualString((src), (dst), TRUE)) \ + +#define DHCPV4_REQOPTION_ENTRY_MATCH(src,dst) \ + (AnscEqualString((src)->Alias, (dst)->Alias, TRUE)) \ + +#define DHCPV4_REQOPTION_ENTRY_MATCH2(src,dst) \ + (AnscEqualString((src), (dst), TRUE)) \ + +#define DHCPV4_CLIENT_INITIATION_CONTEXT(pDhcpc) \ + CONTEXT_LINK_INITIATION_CONTENT(((PCONTEXT_LINK_OBJECT)(pDhcpc))) \ + AnscSListInitializeHeader(&(pDhcpc)->SendOptionList); \ + AnscSListInitializeHeader(&(pDhcpc)->ReqOptionList); \ + (pDhcpc)->maxInstanceOfSend = 0; \ + (pDhcpc)->maxInstanceOfReq = 0; \ + AnscZeroMemory((pDhcpc)->AliasOfReq, sizeof((pDhcpc)->AliasOfReq) ); \ + AnscZeroMemory((pDhcpc)->AliasOfSend, sizeof((pDhcpc)->AliasOfSend) ); \ + +#define DHCPV4_CLIENT_SET_DEFAULTVALUE(pDhcpc) \ + (pDhcpc)->Cfg.bEnabled = FALSE; \ + AnscZeroMemory((pDhcpc)->Cfg.Interface, sizeof((pDhcpc)->Cfg.Interface)); \ + (pDhcpc)->Info.Status = DML_DHCP_STATUS_Disabled; \ + (pDhcpc)->Info.DHCPStatus = DML_DHCPC_STATUS_Init; \ + +#define DHCPV4_SENDOPTION_SET_DEFAULTVALUE(pSendOption) \ + (pSendOption)->bEnabled = FALSE; \ + (pSendOption)->Tag = 0; \ + AnscZeroMemory( (pSendOption)->Value, sizeof( (pSendOption)->Value ) ); \ + + +#define DHCPV4_REQOPTION_SET_DEFAULTVALUE(pReqOption) \ + (pReqOption)->bEnabled = FALSE; \ + (pReqOption)->Order = 0; \ + (pReqOption)->Tag = 0; \ + AnscZeroMemory( (pReqOption)->Value, sizeof( (pReqOption)->Value ) ); \ + + +#define DHCPV4_OPTION_SET_DEFAULTVALUE(pOption) \ + (pOption)->bEnabled = FALSE; \ + +/* + Function declaration +*/ + +ANSC_HANDLE +WanMgr_Dhcpv4Create + ( + VOID + ); + +ANSC_STATUS +WanMgr_Dhcpv4Initialize + ( + ANSC_HANDLE hThisObject + ); + +ANSC_STATUS +WanMgr_Dhcpv4Remove + ( + ANSC_HANDLE hThisObject + ); + +ANSC_STATUS +WanMgr_Dhcpv4RegGetDhcpv4Info + ( + ANSC_HANDLE hThisObject + ); + +ANSC_STATUS +WanMgr_Dhcpv4RegSetDhcpv4Info + ( + ANSC_HANDLE hThisObject + ); + +BOOL +WanMgr_Dhcpv4ClientHasDelayAddedChild + ( + PDHCPC_CONTEXT_LINK_OBJECT hContext + ); + +ANSC_STATUS +WanMgr_Dhcpv4BackendGetDhcpv4Info + ( + ANSC_HANDLE hThisObject + ); + +BOOL +WanMgr_DmlSetIpaddr + ( + PULONG pIPAddr, + PCHAR pString, + ULONG MaxNumber + ); + +BOOL +WanMgr_DmlGetIpaddrString + ( + PUCHAR pString, + PULONG pulStrLength, + PULONG pIPAddr, + ULONG MaxNumber + ); + +ANSC_HANDLE +WanMgr_Dhcpv4GetClientContentbyClient + ( + ANSC_HANDLE hClientContext + ); + + +#endif + + diff --git a/source/WanManager/wanmgr_dhcpv6_apis.c b/source/WanManager/wanmgr_dhcpv6_apis.c new file mode 100644 index 00000000..cface942 --- /dev/null +++ b/source/WanManager/wanmgr_dhcpv6_apis.c @@ -0,0 +1,2648 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2019 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ +#include "wanmgr_data.h" +#include "wanmgr_dhcpv6_apis.h" +#include "wanmgr_interface_sm.h" +#include "wanmgr_sysevents.h" +#include "wanmgr_ipc.h" +#include "wanmgr_utils.h" +#include "wanmgr_net_utils.h" + + +#include +#include +#include +#include +#include "syscfg.h" + +extern int sysevent_fd; +extern token_t sysevent_token; +extern ANSC_HANDLE bus_handle; +extern char g_Subsystem[32]; + +#define IFADDRCONF_ADD 0 +#define IFADDRCONF_REMOVE 1 + + +#ifdef _HUB4_PRODUCT_REQ_ +#include "wanmgr_ipc.h" +#if defined SUCCESS +#undef SUCCESS +#endif +#define SYSEVENT_FIELD_IPV6_DNS_SERVER "wan6_ns" +#define SYSEVENT_FIELD_IPV6_ULA_ADDRESS "ula_address" +#endif + +#if defined(CISCO_CONFIG_DHCPV6_PREFIX_DELEGATION) && defined(_COSA_BCM_MIPS_) +#include +#endif +#define SYSCFG_FORMAT_DHCP6C "tr_dhcpv6c" +#define CLIENT_DUID_FILE "/var/lib/dibbler/client-duid" +#define DHCPS6V_SERVER_RESTART_FIFO "/tmp/ccsp-dhcpv6-server-restart-fifo.txt" + +#define CLIENT_BIN "dibbler-client" + + +static struct { + pthread_t dhcpv6c_thread; +}gDhcpv6c_ctx; + +extern WANMGR_BACKEND_OBJ* g_pWanMgrBE; +static void * dhcpv6c_dbg_thrd(void * in); + +/*erouter topology mode*/ +enum tp_mod { + TPMOD_UNKNOWN, + FAVOR_DEPTH, + FAVOR_WIDTH, +}; + +typedef struct pd_pool { + char start[INET6_ADDRSTRLEN]; + char end[INET6_ADDRSTRLEN]; + int prefix_length; + int pd_length; +} pd_pool_t; + +typedef struct ia_info { + union { + char v6addr[INET6_ADDRSTRLEN]; + char v6pref[INET6_ADDRSTRLEN]; + } value; + + char t1[32], t2[32], iaid[32], pretm[32], vldtm[32]; + int len; +} ia_pd_t; + +typedef struct ipv6_prefix { + char value[INET6_ADDRSTRLEN]; + int len; + //int b_used; +} ipv6_prefix_t; + +#if defined(MULTILAN_FEATURE) +static char v6addr_prev[IPV6_PREF_MAXLEN] = {0}; +#endif + +void _get_shell_output(char * cmd, char * out, int len); +int _get_shell_output2(char * cmd, char * dststr); +static int _prepare_client_conf(PDML_DHCPCV6_CFG pCfg); +static int _dibbler_client_operation(char * arg); + +static DML_DHCPCV6_FULL g_dhcpv6_client; + +static int _dibbler_server_operation(char * arg); +void _cosa_dhcpsv6_refresh_config(); + +static int DHCPv6sDmlTriggerRestart(BOOL OnlyTrigger); + +void _get_shell_output(char * cmd, char * out, int len) +{ + FILE * fp; + char buf[256]; + char * p; + + fp = popen(cmd, "r"); + + if (fp) + { + fgets(buf, sizeof(buf), fp); + + /*we need to remove the \n char in buf*/ + if ((p = strchr(buf, '\n'))) *p = 0; + + strncpy(out, buf, len-1); + + pclose(fp); + } + +} + +int _get_shell_output2(char * cmd, char * dststr) +{ + FILE * fp; + char buf[256]; + char * p; + int bFound = 0; + + fp = popen(cmd, "r"); + + if (fp) + { + while( fgets(buf, sizeof(buf), fp) ) + { + if (strstr(buf, dststr)) + { + bFound = 1;; + break; + } + } + + pclose(fp); + } + + return bFound; +} + +#if defined(CISCO_CONFIG_DHCPV6_PREFIX_DELEGATION) && ! defined(_CBR_PRODUCT_REQ_) && ! defined(_BCI_FEATURE_REQ) + +#else +ANSC_STATUS +WanMgr_DmlDhcpv6SMsgHandler + ( + ANSC_HANDLE hContext + ) +{ + UNREFERENCED_PARAMETER(hContext); + char ret[16] = {0}; + CcspTraceWarning(("%s -- %d Inside WanMgr_DmlDhcpv6SMsgHandler \n", __FUNCTION__, __LINE__)); + CcspTraceWarning(("%s -- %d dhcpv6c_dbg_thrd invoking \n", __FUNCTION__, __LINE__)); + /*we start a thread to hear dhcpv6 client message about prefix/address */ + if ( ( !mkfifo(CCSP_COMMON_FIFO, 0666) || errno == EEXIST ) ) + { + if (pthread_create(&gDhcpv6c_ctx.dhcpv6c_thread, NULL, dhcpv6c_dbg_thrd, NULL) || pthread_detach(gDhcpv6c_ctx.dhcpv6c_thread)) + CcspTraceWarning(("%s error in creating dhcpv6c_dbg_thrd\n", __FUNCTION__)); + } + + //WanMgr_DmlStartDHCP6Client(); +// dhcp v6 client is now initialized in service_wan, no need to initialize from PandM + #if 0 + pthread_t dibblerthread; + pthread_create(&dibblerthread, NULL, &WanMgr_DmlStartDHCP6Client, NULL); + #endif + return 0; +} + +#endif +ANSC_STATUS +WanMgr_DmlDhcpv6Init + ( + ANSC_HANDLE hDml, + PANSC_HANDLE phContext + ) +{ + UNREFERENCED_PARAMETER(hDml); + UNREFERENCED_PARAMETER(phContext); + DSLHDMAGNT_CALLBACK * pEntry = NULL; + CcspTraceWarning(("Inside %s %d \n", __FUNCTION__, __LINE__)); +#if defined(CISCO_CONFIG_DHCPV6_PREFIX_DELEGATION) && ! defined(_CBR_PRODUCT_REQ_) && ! defined(_BCI_FEATURE_REQ) + +#else +/* handle message from wan dchcp6 client */ + WanMgr_DmlDhcpv6SMsgHandler(NULL); + +#endif + + + return ANSC_STATUS_SUCCESS; +} + +/* + Description: + The API retrieves the number of DHCP clients in the system. + */ +ULONG +WanMgr_DmlDhcpv6cGetNumberOfEntries + ( + ANSC_HANDLE hContext + ) +{ + UNREFERENCED_PARAMETER(hContext); + return 1; +} + +/* + Description: + The API retrieves the complete info of the DHCP clients designated by index. The usual process is the caller gets the total number of entries, then iterate through those by calling this API. + Arguments: + ulIndex Indicates the index number of the entry. + pEntry To receive the complete info of the entry. +*/ +static int _get_client_duid(UCHAR * out, int len) +{ + char buf[256] = {0}; + FILE * fp = fopen(CLIENT_DUID_FILE, "r+"); + int i = 0; + int j = 0; + + if(fp) + { + fgets(buf, sizeof(buf), fp); + + if(buf[0]) + { + while(jCfg.InstanceNumber = 1; + + + /*Cfg members*/ + strcpy(buf, SYSCFG_FORMAT_DHCP6C"_alias"); + memset(pEntry->Cfg.Alias, 0, sizeof(pEntry->Cfg.Alias)); + if( syscfg_get( NULL, buf, out, sizeof(out)) == 0 ) + { + strncpy(pEntry->Cfg.Alias, out, sizeof(out)); + } + + pEntry->Cfg.SuggestedT1 = pEntry->Cfg.SuggestedT2 = 0; + + strcpy(buf, SYSCFG_FORMAT_DHCP6C"_t1"); + memset(out, 0, sizeof(out)); + if( syscfg_get( NULL, buf, out, sizeof(out)) == 0 ) + { + sscanf(out, "%lu", &pEntry->Cfg.SuggestedT1); + } + + strcpy(buf, SYSCFG_FORMAT_DHCP6C"_t2"); + memset(out, 0, sizeof(out)); + if( syscfg_get( NULL, buf, out, sizeof(out)) == 0 ) + { + sscanf(out, "%lu", &pEntry->Cfg.SuggestedT2); + } + + /*pEntry->Cfg.Interface stores interface name, dml will calculate the full path name*/ + strcpy(pEntry->Cfg.Interface, DML_DHCP_CLIENT_IFNAME); + + strcpy(buf, SYSCFG_FORMAT_DHCP6C"_requested_options"); + memset(out, 0, sizeof(out)); + memset(pEntry->Cfg.RequestedOptions, 0, sizeof(pEntry->Cfg.RequestedOptions)); + if( syscfg_get( NULL, buf, out, sizeof(out)) == 0 ) + { + strncpy(pEntry->Cfg.RequestedOptions, out, sizeof(out)); + } + + strcpy(buf, SYSCFG_FORMAT_DHCP6C"_enabled"); + memset(out, 0, sizeof(out)); + if( syscfg_get( NULL, buf, out, sizeof(out)) == 0 ) + { + pEntry->Cfg.bEnabled = (out[0] == '1') ? TRUE:FALSE; + } + + strcpy(buf, SYSCFG_FORMAT_DHCP6C"_iana_enabled"); + memset(out, 0, sizeof(out)); + if( syscfg_get( NULL, buf, out, sizeof(out)) == 0 ) + { + pEntry->Cfg.RequestAddresses = (out[0] == '1') ? TRUE:FALSE; + } + + strcpy(buf, SYSCFG_FORMAT_DHCP6C"_iapd_enabled"); + memset(out, 0, sizeof(out)); + if( syscfg_get( NULL, buf, out, sizeof(out)) == 0 ) + { + pEntry->Cfg.RequestPrefixes = (out[0] == '1') ? TRUE:FALSE; + } + + strcpy(buf, SYSCFG_FORMAT_DHCP6C"_rapidcommit_enabled"); + memset(out, 0, sizeof(out)); + if( syscfg_get( NULL, buf, out, sizeof(out)) == 0 ) + { + pEntry->Cfg.RapidCommit = (out[0] == '1') ? TRUE:FALSE; + } + + /*Info members*/ + if (pEntry->Cfg.bEnabled) + pEntry->Info.Status = DML_DHCP_STATUS_Enabled; + else + pEntry->Info.Status = DML_DHCP_STATUS_Disabled; + + /*TODO: supported options*/ + + _get_client_duid(pEntry->Info.DUID, sizeof(pEntry->Info.DUID)); + + + /*if we don't have alias, set a default one*/ + + + AnscCopyMemory(&g_dhcpv6_client, pEntry, sizeof(g_dhcpv6_client)); + + if (pEntry->Cfg.bEnabled) + _prepare_client_conf(&pEntry->Cfg); + + return ANSC_STATUS_SUCCESS; +} + +ANSC_STATUS +WanMgr_DmlDhcpv6cSetValues + ( + ANSC_HANDLE hContext, + ULONG ulIndex, + ULONG ulInstanceNumber, + char* pAlias + ) +{ + UNREFERENCED_PARAMETER(hContext); + UNREFERENCED_PARAMETER(ulInstanceNumber); + + if (ulIndex) + { + return ANSC_STATUS_FAILURE; + } + + strcpy(g_dhcpv6_client.Cfg.Alias, pAlias); + + + return ANSC_STATUS_SUCCESS; +} + +/* + Description: + The API adds DHCP client. + Arguments: + pEntry Caller fills in pEntry->Cfg, except Alias field. Upon return, callee fills pEntry->Cfg.Alias field and as many as possible fields in pEntry->Info. +*/ +ANSC_STATUS +WanMgr_DmlDhcpv6cAddEntry + ( + ANSC_HANDLE hContext, + PDML_DHCPCV6_FULL pEntry + ) +{ + UNREFERENCED_PARAMETER(hContext); + UNREFERENCED_PARAMETER(pEntry); + return ANSC_STATUS_SUCCESS; +} + +/* + Description: + The API removes the designated DHCP client entry. + Arguments: + pAlias The entry is identified through Alias. +*/ +ANSC_STATUS +WanMgr_DmlDhcpv6cDelEntry + ( + ANSC_HANDLE hContext, + ULONG ulInstanceNumber + ) +{ + UNREFERENCED_PARAMETER(hContext); + UNREFERENCED_PARAMETER(ulInstanceNumber); + return ANSC_STATUS_SUCCESS; +} + +/* +A sample content of client.conf +iface wan0 { + rapid-commit yes + ia { + t1 1000 + t2 2000 + } + pd { + t1 1000 + t2 2000 + } +} +*/ +#define TMP_CLIENT_CONF "/tmp/.dibbler_client_conf" +#define CLIENT_CONF_LOCATION "/etc/dibbler/client.conf" +#define TMP_SERVER_CONF "/tmp/.dibbler_server_conf" +#define SERVER_CONF_LOCATION "/etc/dibbler/server.conf" + +static int _prepare_client_conf(PDML_DHCPCV6_CFG pCfg) +{ + FILE * fp = fopen(TMP_CLIENT_CONF, "w+"); + char line[256] = {0}; + + if (fp) + { + /*we need this to get IANA IAPD info from dibbler*/ + fprintf(fp, "notify-scripts\n"); + + fprintf(fp, "iface %s {\n", pCfg->Interface); + + if (pCfg->RapidCommit) + fprintf(fp, " rapid-commit yes\n"); + + if (pCfg->RequestAddresses) + { + fprintf(fp, " ia {\n"); + + if (pCfg->SuggestedT1) + { + memset(line, 0, sizeof(line)); + snprintf(line, sizeof(line)-1, " t1 %lu\n", pCfg->SuggestedT1); + fprintf(fp, "%s", line); + } + + if (pCfg->SuggestedT2) + { + memset(line, 0, sizeof(line)); + snprintf(line, sizeof(line)-1, " t2 %lu\n", pCfg->SuggestedT2); + fprintf(fp, "%s", line); + } + + fprintf(fp, " }\n"); + } + + if (pCfg->RequestPrefixes) + { + fprintf(fp, " pd {\n"); + + if (pCfg->SuggestedT1) + { + memset(line, 0, sizeof(line)); + snprintf(line, sizeof(line)-1, " t1 %lu\n", pCfg->SuggestedT1); + fprintf(fp, "%s", line); + } + + if (pCfg->SuggestedT2) + { + memset(line, 0, sizeof(line)); + snprintf(line, sizeof(line)-1, " t2 %lu\n", pCfg->SuggestedT2); + fprintf(fp, "%s", line); + } + + fprintf(fp, " }\n"); + } + + fprintf(fp, "}\n"); + + fclose(fp); + } + + /*we will copy the updated conf file at once*/ + if (rename(TMP_CLIENT_CONF, CLIENT_CONF_LOCATION)) + CcspTraceWarning(("%s rename failed %s\n", __FUNCTION__, strerror(errno))); + + return 0; +} + +static int _dibbler_client_operation(char * arg) +{ + char cmd[256] = {0}; + char out[256] = {0}; +#if defined (INTEL_PUMA7) + int watchdog = NO_OF_RETRY; +#endif + + if (!strncmp(arg, "stop", 4)) + { + CcspTraceInfo(("%s stop\n", __func__)); + /*TCXB6 is also calling service_dhcpv6_client.sh but the actuall script is installed from meta-rdk-oem layer as the intel specific code + had to be removed */ +#if defined(CISCO_CONFIG_DHCPV6_PREFIX_DELEGATION) && ! defined(DHCPV6_PREFIX_FIX) + sysevent_set(sysevent_fd, sysevent_token, "dhcpv6_client-stop", "", 0); +#else + system("/etc/utopia/service.d/service_dhcpv6_client.sh disable"); +#endif + +#ifdef _COSA_BCM_ARM_ + sprintf(cmd, "killall %s", CLIENT_BIN); + system(cmd); + sleep(2); + sprintf(cmd, "ps -A|grep %s", CLIENT_BIN); + _get_shell_output(cmd, out, sizeof(out)); + if (strstr(out, CLIENT_BIN)) + { + sprintf(cmd, "killall -9 %s", CLIENT_BIN); + system(cmd); + } +#endif + } + else if (!strncmp(arg, "start", 5)) + { + CcspTraceInfo(("%s start\n", __func__)); + +#if defined(INTEL_PUMA7) || defined(_COSA_BCM_ARM_) + +#if defined(INTEL_PUMA7) + //Intel Proposed RDKB Generic Bug Fix from XB6 SDK + /* Waiting for the TLV file to be parsed correctly so that the right erouter mode can be used in the code below. + For ANYWAN please extend the below code to support the case of TLV config file not being there. */ + do{ + sprintf(cmd, "sysevent get TLV202-status"); + _get_shell_output(cmd, out, sizeof(out)); + fprintf( stderr, "\n%s:%s(): Waiting for CcspGwProvApp to parse TLV config file\n", __FILE__, __FUNCTION__); + sleep(1);//sleep(1) is to avoid lots of trace msgs when there is latency + watchdog--; + }while((!strstr(out,"success")) && (watchdog != 0)); + + if(watchdog == 0) + { + //When 60s have passed and the file is still not configured by CcspGwprov module + fprintf(stderr, "\n%s()%s(): TLV data has not been initialized by CcspGwProvApp.Continuing with the previous configuration\n",__FILE__, __FUNCTION__); + } +#endif +#ifndef _HUB4_PRODUCT_REQ_ + /* This wait loop is not required as we are not configuring IPv6 address on erouter0 interface */ + sprintf(cmd, "syscfg get last_erouter_mode"); + _get_shell_output(cmd, out, sizeof(out)); + /* TODO: To be fixed by Comcast + IPv6 address assigned to erouter0 gets deleted when erouter_mode=3(IPV4 and IPV6 both) + Don't start v6 service in parallel. Wait for wan-status to be set to 'started' by IPv4 DHCP client. + */ + if (strstr(out, "3"))// If last_erouter_mode is both IPV4/IPV6 + { + do{ + sprintf(cmd, "sysevent get wan-status"); + _get_shell_output(cmd, out, sizeof(out)); + CcspTraceInfo(("%s waiting for wan-status to started\n", __func__)); + sleep(1);//sleep(1) is to avoid lots of trace msgs when there is latency + }while(!strstr(out,"started")); + } +#endif +#endif + /*This is for ArrisXB6 */ + /*TCXB6 is also calling service_dhcpv6_client.sh but the actuall script is installed from meta-rdk-oem layer as the intel specific code + had to be removed */ + CcspTraceInfo(("%s Callin service_dhcpv6_client.sh enable \n", __func__)); +#if defined(CISCO_CONFIG_DHCPV6_PREFIX_DELEGATION) && ! defined(DHCPV6_PREFIX_FIX) + sysevent_set(sysevent_fd, sysevent_token, "dhcpv6_client-start", "", 0); +#else + system("/etc/utopia/service.d/service_dhcpv6_client.sh enable"); +#endif + +#ifdef _COSA_BCM_ARM_ + /* Dibbler-init is called to set the pre-configuration for dibbler */ + CcspTraceInfo(("%s dibbler-init.sh Called \n", __func__)); + system("/etc/dibbler/dibbler-init.sh"); + /*Start Dibber client for tchxb6*/ + CcspTraceInfo(("%s Dibbler Client Started \n", __func__)); + sprintf(cmd, "%s start", CLIENT_BIN); + system(cmd); +#endif + } + else if (!strncmp(arg, "restart", 7)) + { + _dibbler_client_operation("stop"); + _dibbler_client_operation("start"); + } + + return 0; +} +/*internal.c will call this when obtained Client and SentOptions. so we don't need to start service in getEntry for Client and SentOptions.*/ +int WanMgr_DmlStartDHCP6Client() +{ + pthread_detach(pthread_self()); +#if defined(_COSA_INTEL_XB3_ARM_) + CcspTraceInfo(("Not restarting ti_dhcp6c for XB3 case\n")); +#else + // _dibbler_client_operation("restart"); +#endif + return 0; +} +/* +Description: + The API re-configures the designated DHCP client entry. +Arguments: + pAlias The entry is identified through Alias. + pEntry The new configuration is passed through this argument, even Alias field can be changed. +*/ +ANSC_STATUS +WanMgr_DmlDhcpv6cSetCfg + ( + ANSC_HANDLE hContext, + PDML_DHCPCV6_CFG pCfg + ) +{ + UNREFERENCED_PARAMETER(hContext); + char buf[256] = {0}; + char out[256] = {0}; + int need_to_restart_service = 0; + + if (pCfg->InstanceNumber != 1) + return ANSC_STATUS_FAILURE; + + + if (!AnscEqualString((char*)pCfg->Alias, (char*)g_dhcpv6_client.Cfg.Alias, TRUE)) + { + strcpy(buf, SYSCFG_FORMAT_DHCP6C"_alias"); + syscfg_set_string(buf,(char*)pCfg->Alias); + } + + if (pCfg->SuggestedT1 != g_dhcpv6_client.Cfg.SuggestedT1) + { + strcpy(buf, SYSCFG_FORMAT_DHCP6C"_t1"); + sprintf(out, "%lu", pCfg->SuggestedT1); + syscfg_set_string(buf, out); + need_to_restart_service = 1; + } + + if (pCfg->SuggestedT2 != g_dhcpv6_client.Cfg.SuggestedT2) + { + strcpy(buf, SYSCFG_FORMAT_DHCP6C"_t2"); + sprintf(out, "%lu", pCfg->SuggestedT2); + syscfg_set_string(buf, out); + need_to_restart_service = 1; + } + + if (!AnscEqualString((char*)pCfg->RequestedOptions, (char*)g_dhcpv6_client.Cfg.RequestedOptions, TRUE)) + { + strcpy(buf, SYSCFG_FORMAT_DHCP6C"_requested_options"); + syscfg_set_string(buf, (char*)pCfg->RequestedOptions); + need_to_restart_service = 1; + } + + if (pCfg->bEnabled != g_dhcpv6_client.Cfg.bEnabled) + { + strcpy(buf, SYSCFG_FORMAT_DHCP6C"_enabled"); + out[0] = pCfg->bEnabled ? '1':'0'; + out[1] = 0; + syscfg_set_string(buf, out); + need_to_restart_service = 1; + } + + if (pCfg->RequestAddresses != g_dhcpv6_client.Cfg.RequestAddresses) + { + strcpy(buf, SYSCFG_FORMAT_DHCP6C"_iana_enabled"); + out[0] = pCfg->RequestAddresses ? '1':'0'; + out[1] = 0; + syscfg_set_string(buf, out); + need_to_restart_service = 1; + } + + if (pCfg->RequestPrefixes != g_dhcpv6_client.Cfg.RequestPrefixes) + { + strcpy(buf, SYSCFG_FORMAT_DHCP6C"_iapd_enabled"); + out[0] = pCfg->RequestPrefixes ? '1':'0'; + out[1] = 0; + syscfg_set_string(buf, out); + need_to_restart_service = 1; + } + + if (pCfg->RapidCommit != g_dhcpv6_client.Cfg.RapidCommit) + { + strcpy(buf, SYSCFG_FORMAT_DHCP6C"_rapidcommit_enabled"); + out[0] = pCfg->RapidCommit ? '1':'0'; + out[1] = 0; + syscfg_set_string(buf, out); + need_to_restart_service = 1; + } + + /*update dibbler-client service if necessary*/ + if (need_to_restart_service) + { + if ( pCfg->bEnabled != g_dhcpv6_client.Cfg.bEnabled && !pCfg->bEnabled ) + _dibbler_client_operation("stop"); + else if (pCfg->bEnabled != g_dhcpv6_client.Cfg.bEnabled && pCfg->bEnabled ) + { + _prepare_client_conf(pCfg); + _dibbler_client_operation("restart"); + } + else if (pCfg->bEnabled == g_dhcpv6_client.Cfg.bEnabled && !pCfg->bEnabled) + { + /*do nothing*/ + } + else if (pCfg->bEnabled == g_dhcpv6_client.Cfg.bEnabled && pCfg->bEnabled) + { + _prepare_client_conf(pCfg); + _dibbler_client_operation("restart"); + } + } + + AnscCopyMemory(&g_dhcpv6_client.Cfg, pCfg, sizeof(DML_DHCPCV6_CFG)); + + return ANSC_STATUS_SUCCESS; +} + +ANSC_STATUS +WanMgr_DmlDhcpv6cGetCfg + ( + ANSC_HANDLE hContext, + PDML_DHCPCV6_CFG pCfg + ) +{ + UNREFERENCED_PARAMETER(hContext); + /*for rollback*/ + if (pCfg->InstanceNumber != 1) + return ANSC_STATUS_FAILURE; + + AnscCopyMemory(pCfg, &g_dhcpv6_client.Cfg, sizeof(DML_DHCPCV6_CFG)); + + return ANSC_STATUS_SUCCESS; +} + +BOOL +WanMgr_DmlDhcpv6cGetEnabled + ( + ANSC_HANDLE hContext + ) +{ + UNREFERENCED_PARAMETER(hContext); + BOOL bEnabled = FALSE; + char out[256] = {0}; + BOOL dibblerEnabled = FALSE; + +// For XB3, AXB6 if dibbler flag enabled, check dibbler-client process status +#if defined(_COSA_INTEL_XB3_ARM_) || defined(INTEL_PUMA7) + char buf[8]; + if(( syscfg_get( NULL, "dibbler_client_enable", buf, sizeof(buf))==0) && (strcmp(buf, "true") == 0)) + { + dibblerEnabled = TRUE; + } +#endif + +#if defined (_COSA_BCM_ARM_) || defined (_HUB4_PRODUCT_REQ_) + FILE *fp = popen("ps |grep -i dibbler-client | grep -v grep", "r"); + +#elif defined (_XF3_PRODUCT_REQ_) + FILE *fp = popen("/usr/sbin/dibbler-client status |grep client", "r"); + +#else + FILE *fp; + // For XB3, AXB6 if dibbler flag enabled, check dibbler-client process status + if(dibblerEnabled) + fp = popen("ps |grep -i dibbler-client | grep -v grep", "r"); + else + fp = popen("ps |grep -i ti_dhcp6c | grep erouter0 | grep -v grep", "r"); +#endif + + if ( fp != NULL){ + if ( fgets(out, sizeof(out), fp) != NULL ){ +#if defined (_COSA_BCM_ARM_) || defined (_HUB4_PRODUCT_REQ_) + if ( _ansc_strstr(out, "dibbler-client") ) + bEnabled = TRUE; +#elif defined (_XF3_PRODUCT_REQ_) + if ( strstr(out, "RUNNING,") ) + bEnabled = TRUE; +#else + // For XB3, AXB6 if dibbler flag enabled, check dibbler-client process status + if ( dibblerEnabled && _ansc_strstr(out, "dibbler-client") ) + bEnabled = TRUE; + if ( _ansc_strstr(out, "erouter_dhcp6c") ) + bEnabled = TRUE; +#endif + } + pclose(fp); + } + + return bEnabled; +} + +ANSC_STATUS +WanMgr_DmlDhcpv6cGetInfo + ( + ANSC_HANDLE hContext, + ULONG ulInstanceNumber, + PDML_DHCPCV6_INFO pInfo + ) +{ + UNREFERENCED_PARAMETER(ulInstanceNumber); + PDML_DHCPCV6_FULL pDhcpc = (PDML_DHCPCV6_FULL)hContext; + + _get_client_duid(g_dhcpv6_client.Info.DUID, sizeof(pInfo->DUID)); + + if (pDhcpc) + { + if (pDhcpc->Cfg.bEnabled) + g_dhcpv6_client.Info.Status = pDhcpc->Info.Status = DML_DHCP_STATUS_Enabled; + else + g_dhcpv6_client.Info.Status = pDhcpc->Info.Status = DML_DHCP_STATUS_Disabled; + } + + AnscCopyMemory(pInfo, &g_dhcpv6_client.Info, sizeof(DML_DHCPCV6_INFO)); + + return ANSC_STATUS_SUCCESS; +} + +#define CLIENT_SERVER_INFO_FILE "/tmp/.dibbler-info/client_server" +/*this file's format: + line 1: addr server_ipv6_addr + line 2: duid server_duid*/ +/* this memory need to be freed by caller */ +ANSC_STATUS +WanMgr_DmlDhcpv6cGetServerCfg + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber, + PDML_DHCPCV6_SVR *ppCfg, + PULONG pSize + ) +{ + UNREFERENCED_PARAMETER(hContext); + UNREFERENCED_PARAMETER(ulClientInstanceNumber); + FILE * fp = fopen(CLIENT_SERVER_INFO_FILE, "r+"); + + *pSize = 0; + if (fp) + { + char buf[1024] = {0}; + char val[1024] = {0}; + int entry_count = 0; + + /*we only support one entry of ServerCfg*/ + *ppCfg = (PDML_DHCPCV6_SVR)AnscAllocateMemory( sizeof(DML_DHCPCV6_SVR) ); + memset(*ppCfg, 0, sizeof(DML_DHCPCV6_SVR)); + + /*InformationRefreshTime not supported*/ + strcpy((char*)(*ppCfg)->InformationRefreshTime, "0001-01-01T00:00:00Z"); + + while(fgets(buf, sizeof(buf)-1, fp)) + { + memset(val, 0, sizeof(val)); + if (sscanf(buf, "addr %s", val)) + { + strcpy((char*)(*ppCfg)->SourceAddress, val); + entry_count |= 1; + } + else if (sscanf(buf, "duid %s", val)) + { + unsigned int i = 0, j = 0; + /*the file stores duid in this format 00:01:..., we need to transfer it to continuous hex*/ + + for (i=0; iDUID)-1; i++) + { + if (val[i] != ':') + ((*ppCfg)->DUID)[j++] = val[i]; + } + + entry_count |= 2; + } + + /*only we have both addr and duid we think we have a whole server-info*/ + if (entry_count == 3) + *pSize = 1; + + memset(buf, 0, sizeof(buf)); + } + fclose(fp); + } + + return ANSC_STATUS_SUCCESS; +} + +/* + Description: + The API initiates a DHCP client renewal. + Arguments: + pAlias The entry is identified through Alias. +*/ +ANSC_STATUS +WanMgr_DmlDhcpv6cRenew + ( + ANSC_HANDLE hContext, + ULONG ulInstanceNumber + ) +{ + UNREFERENCED_PARAMETER(hContext); + UNREFERENCED_PARAMETER(ulInstanceNumber); + char cmd[256] = {0}; + + sprintf(cmd, "killall -SIGUSR2 %s", CLIENT_BIN); + system(cmd); + + return ANSC_STATUS_SUCCESS; +} + +/* + * DHCP Client Send/Req Option + * + * The options are managed on top of a DHCP client, + * which is identified through pClientAlias + */ +#define SYSCFG_DHCP6C_SENT_OPTION_FORMAT "tr_dhcp6c_sent_option_%lu" +static int g_sent_option_num; +static DML_DHCPCV6_SENT * g_sent_options; +static int g_recv_option_num = 0; +static DML_DHCPCV6_RECV * g_recv_options = NULL; + +ULONG +WanMgr_DmlDhcpv6cGetNumberOfSentOption + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber + ) +{ + UNREFERENCED_PARAMETER(hContext); + UNREFERENCED_PARAMETER(ulClientInstanceNumber); + char buf[256] = {0}; + char out[256] = {0}; + + + strncpy(buf, "tr_dhcp6c_sent_option_num", sizeof(out)); + if( syscfg_get( NULL, buf, out, sizeof(out)) == 0 ) + { + g_sent_option_num = atoi(out); + } + + if (g_sent_option_num) + { + g_sent_options = (DML_DHCPCV6_SENT *)AnscAllocateMemory(sizeof(DML_DHCPCV6_SENT)* g_sent_option_num); + } + + return g_sent_option_num; + +} + +#define CLIENT_SENT_OPTIONS_FILE "/tmp/.dibbler-info/client_sent_options" +/*this function will generate sent_option info file to dibbler-client, + the format of CLIENT_SENT_OPTIONS_FILE: + option-type:option-len:option-data*/ +static int _write_dibbler_sent_option_file(void) +{ + FILE * fp = fopen(CLIENT_SENT_OPTIONS_FILE, "w+"); + int i = 0; + + if (fp) + { + for (i=0; i g_sent_option_num - 1 || !g_sent_options) + { + return ANSC_STATUS_FAILURE; + } + + /*note in syscfg, sent_options start from 1*/ + sprintf(namespace, SYSCFG_DHCP6C_SENT_OPTION_FORMAT, ulIndex+1); + memset(buf, 0, sizeof(buf)); + memset(out, 0, sizeof(out)); + if( syscfg_get( NULL, namespace, out, sizeof(out)) == 0 ) + { + sscanf(out, "%lu", &pEntry->InstanceNumber); + } + + memset(buf, 0, sizeof(buf)); + memset(out, 0, sizeof(out)); + snprintf(buf, sizeof(buf), "%s_alias", namespace); + if( syscfg_get( NULL, buf, out, sizeof(out)) == 0 ) + { + strncpy(pEntry->Alias, out, sizeof(pEntry->Alias)); + } + + memset(buf, 0, sizeof(buf)); + memset(out, 0, sizeof(out)); + snprintf(buf, sizeof(buf), "%s_enabled", namespace); + if( syscfg_get( NULL, buf, out, sizeof(out)) == 0 ) + { + pEntry->bEnabled = (out[0] == '1') ? TRUE:FALSE; + } + + memset(buf, 0, sizeof(buf)); + memset(out, 0, sizeof(out)); + snprintf(buf, sizeof(buf), "%s_tag", namespace); + if( syscfg_get( NULL, namespace, out, sizeof(out)) == 0 ) + { + sscanf(out, "%lu", &pEntry->Tag); + } + + memset(buf, 0, sizeof(buf)); + memset(out, 0, sizeof(out)); + snprintf(buf, sizeof(buf), "%s_value", namespace); + if( syscfg_get( NULL, buf, out, sizeof(out)) == 0 ) + { + strncpy(pEntry->Value, out, sizeof(pEntry->Value)); + } + + AnscCopyMemory( &g_sent_options[ulIndex], pEntry, sizeof(DML_DHCPCV6_SENT)); + + /*we only wirte to file when obtaining the last entry*/ + if (ulIndex == g_sent_option_num-1) + _write_dibbler_sent_option_file(); + + + return ANSC_STATUS_SUCCESS; +} + + +ANSC_STATUS +WanMgr_DmlDhcpv6cGetSentOptionbyInsNum + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber, + PDML_DHCPCV6_SENT pEntry + ) +{ + UNREFERENCED_PARAMETER(hContext); + UNREFERENCED_PARAMETER(ulClientInstanceNumber); + ULONG index = 0; + + for( index=0; indexInstanceNumber == g_sent_options[index].InstanceNumber ) + { + AnscCopyMemory( pEntry, &g_sent_options[index], sizeof(DML_DHCPCV6_SENT)); + return ANSC_STATUS_SUCCESS; + } + } + + return ANSC_STATUS_FAILURE; +} + + +ANSC_STATUS +WanMgr_DmlDhcpv6cSetSentOptionValues + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber, + ULONG ulIndex, + ULONG ulInstanceNumber, + char* pAlias + ) +{ + UNREFERENCED_PARAMETER(hContext); + char out[256] = {0}; + char namespace[256] = {0}; + + if (ulClientInstanceNumber != g_dhcpv6_client.Cfg.InstanceNumber) + return ANSC_STATUS_FAILURE; + + if ( (int)ulIndex+1 > g_sent_option_num ) + return ANSC_STATUS_SUCCESS; + + g_sent_options[ulIndex].InstanceNumber = ulInstanceNumber; + AnscCopyString( (char*)g_sent_options[ulIndex].Alias, pAlias); + + + sprintf(namespace, SYSCFG_DHCP6C_SENT_OPTION_FORMAT, ulIndex+1); + snprintf(out, sizeof(out), "%lu", ulInstanceNumber); + syscfg_set_string(namespace, out); + + snprintf(out, sizeof(out), "%s_alias", namespace); + syscfg_set_string(out, pAlias); + + return ANSC_STATUS_SUCCESS; +} + +static int _syscfg_add_sent_option(PDML_DHCPCV6_SENT pEntry, int index) +{ + char out[256] = {0}; + char buf[256] = {0}; + char namespace[256] = {0}; + + if (!pEntry) + return -1; + + sprintf(namespace, SYSCFG_DHCP6C_SENT_OPTION_FORMAT, index); + snprintf(out, sizeof(out), "%lu", pEntry->InstanceNumber); + syscfg_set_string(namespace, out); + + snprintf(out, sizeof(out), "%s_alias", namespace); + syscfg_set_string(out, pEntry->Alias); + + snprintf(buf, sizeof(buf), "%s_enabled", namespace); + if (pEntry->bEnabled) + sprintf(out, "1"); + else + sprintf(out, "0"); + syscfg_set_string(buf, out); + + snprintf(buf, sizeof(buf), "%s_tag", namespace); + snprintf(out, sizeof(out)-1, "%lu", pEntry->Tag); + syscfg_set_string(buf, out); + + snprintf(buf, sizeof(buf), "%s_value", namespace); + syscfg_set_string(buf, pEntry->Value); + + return 0; +} + +ANSC_STATUS +WanMgr_DmlDhcpv6cAddSentOption + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber, + PDML_DHCPCV6_SENT pEntry + ) +{ + UNREFERENCED_PARAMETER(hContext); + char out[256] = {0}; + char namespace[256] = {0}; + + /*we only have one client*/ + if (ulClientInstanceNumber != g_dhcpv6_client.Cfg.InstanceNumber) + return ANSC_STATUS_FAILURE; + + g_sent_options = realloc(g_sent_options, (++g_sent_option_num)* sizeof(DML_DHCPCV6_SENT)); + if (!g_sent_options) + return ANSC_STATUS_FAILURE; + + _syscfg_add_sent_option(pEntry, g_sent_option_num); + + snprintf(out, sizeof(out)-1, "%d", g_sent_option_num); + syscfg_set_string("tr_dhcp6c_sent_option_num", out); + + g_sent_options[g_sent_option_num-1] = *pEntry; + + /*if the added entry is disabled, don't update dibbler-info file*/ + if (pEntry->bEnabled) + { + _write_dibbler_sent_option_file(); + _dibbler_client_operation("restart"); + } + + return ANSC_STATUS_SUCCESS; +} + +ANSC_STATUS +WanMgr_DmlDhcpv6cDelSentOption + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber, + ULONG ulInstanceNumber + ) +{ + UNREFERENCED_PARAMETER(hContext); + char out[256] = {0}; + char namespace[256] = {0}; + int i = 0; + int j = 0; + int saved_enable = 0; + + /*we only have one client*/ + if (ulClientInstanceNumber != g_dhcpv6_client.Cfg.InstanceNumber) + return ANSC_STATUS_FAILURE; + + + for (i=0; iInstanceNumber == g_sent_options[index].InstanceNumber ) + { + p_old_entry = &g_sent_options[index]; + + + /*handle syscfg*/ + sprintf(namespace, SYSCFG_DHCP6C_SENT_OPTION_FORMAT, index+1); + + if (!AnscEqualString(pEntry->Alias, p_old_entry->Alias, TRUE)) + { + sprintf(buf, "%s_alias", namespace); + syscfg_set_string(buf, pEntry->Alias); + } + + if (pEntry->bEnabled != p_old_entry->bEnabled) + { + if (pEntry->bEnabled) + sprintf(out, "1"); + else + sprintf(out, "0"); + sprintf(buf, "%s_enabled", namespace); + syscfg_set_string(buf, out); + need_restart_service = 1; + } + + + if (pEntry->Tag != p_old_entry->Tag) + { + sprintf(buf, "%s_tag", namespace); + snprintf(out, sizeof(out)-1, "%lu", pEntry->Tag); + syscfg_set_string(buf, out); + need_restart_service = 1; + } + + if (!AnscEqualString(pEntry->Value, p_old_entry->Value, TRUE)) + { + sprintf(buf, "%s_value", namespace); + syscfg_set_string(buf, pEntry->Value); + need_restart_service = 1; + } + + AnscCopyMemory( &g_sent_options[index], pEntry, sizeof(DML_DHCPCV6_SENT)); + + if (need_restart_service) + { + _write_dibbler_sent_option_file(); + _dibbler_client_operation("restart"); + } + + return ANSC_STATUS_SUCCESS; + } + } + + return ANSC_STATUS_SUCCESS; +} + +/* This is to get all + */ +#define CLIENT_RCVED_OPTIONS_FILE "/tmp/.dibbler-info/client_received_options" +/*this file has the following format: + ...... + line n : opt-len opt-type opt-data(HexBinary) + ...... +*/ +ANSC_STATUS +WanMgr_DmlDhcpv6cGetReceivedOptionCfg + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber, + PDML_DHCPCV6_RECV *ppEntry, + PULONG pSize + ) +{ + UNREFERENCED_PARAMETER(hContext); + UNREFERENCED_PARAMETER(ulClientInstanceNumber); + FILE * fp = fopen(CLIENT_RCVED_OPTIONS_FILE, "r+"); + SLIST_HEADER option_list; + DML_DHCPCV6_RECV * p_rcv = NULL; + char buf[1024] = {0}; + PSINGLE_LINK_ENTRY pSLinkEntry = NULL; + ULONG ulIndex = 0; + + AnscSListInitializeHeader( &option_list ); + + if (fp) + { + while (fgets(buf, sizeof(buf)-1, fp)) + { + int opt_len = 0; + char opt_data[1024] = {0}; + char * p = NULL; + + p_rcv = (DML_DHCPCV6_RECV * )AnscAllocateMemory(sizeof(*p_rcv)); + memset(p_rcv, 0, sizeof(*p_rcv)); + if (!p_rcv) + break; + + if (sscanf(buf, "%d %lu", &opt_len, &p_rcv->Tag) != 2) + { + AnscFreeMemory(p_rcv); /*RDKB-6780, CID-33399, free unused resource*/ + p_rcv = NULL; + continue; + } + + /*don't trust opt_len record in file, calculate by self*/ + if ((p = strrchr(buf, ' '))) + { + p++; + if ((unsigned int)opt_len*2 < (strlen(buf)- (p-buf))) + opt_len = (strlen(buf)- (p-buf))/2; + } + else + { + AnscFreeMemory(p_rcv); /*RDKB-6780, CID-33399, free unused resource*/ + p_rcv = NULL; + continue; + } + + if ((unsigned int)opt_len*2 >= sizeof(p_rcv->Value)) + { + AnscFreeMemory(p_rcv); /*RDKB-6780, CID-33399, free unused resource*/ + p_rcv = NULL; + continue; + } + + /*finally we are safe, copy string into Value*/ + if (sscanf(buf, "%*d %*d %s", p_rcv->Value) != 1) + { + AnscFreeMemory(p_rcv); /*RDKB-6780, CID-33399, free unused resource*/ + p_rcv = NULL; + continue; + } + /*we only support one server, hardcode it*/ + strcpy((char*)p_rcv->Server, "Device.DHCPv6.Client.1.Server.1"); + AnscSListPushEntryAtBack(&option_list, &p_rcv->Link); + + memset(buf, 0, sizeof(buf)); + } + fclose(fp); + } + + if (!AnscSListGetFirstEntry(&option_list)) + { + *pSize = 0; + return ANSC_STATUS_SUCCESS; + } + + *ppEntry = (PDML_DHCPCV6_RECV)AnscAllocateMemory( AnscSListQueryDepth(&option_list) *sizeof(DML_DHCPCV6_RECV) ); + + pSLinkEntry = AnscSListGetFirstEntry(&option_list); + + for ( ulIndex = 0; ulIndex < option_list.Depth; ulIndex++ ) + { + p_rcv = ACCESS_DHCPV6_RECV_LINK_OBJECT(pSLinkEntry); + pSLinkEntry = AnscSListGetNextEntry(pSLinkEntry); + + AnscCopyMemory( *ppEntry + ulIndex, p_rcv, sizeof(*p_rcv) ); + AnscFreeMemory(p_rcv); + } + + *pSize = AnscSListQueryDepth(&option_list); + + /* we need keep this for reference in server*/ + if ( g_recv_options ) + AnscFreeMemory(g_recv_options); + + g_recv_option_num = *pSize; + g_recv_options = (DML_DHCPCV6_RECV *)AnscAllocateMemory( sizeof(DML_DHCPCV6_RECV) * g_recv_option_num ); + AnscCopyMemory(g_recv_options, *ppEntry, sizeof(DML_DHCPCV6_RECV) * g_recv_option_num); + + return ANSC_STATUS_SUCCESS; +} + +static int DHCPv6sDmlTriggerRestart(BOOL OnlyTrigger) +{ + int fd = 0; + char str[32] = "restart"; + + #if defined(CISCO_CONFIG_DHCPV6_PREFIX_DELEGATION) && ! defined(DHCPV6_PREFIX_FIX) + sysevent_set(sysevent_fd, sysevent_token, "dhcpv6_server-restart", "" , 0); + #else + + //not restart really.we only need trigger pthread to check whether there is pending action. + + fd= open(DHCPS6V_SERVER_RESTART_FIFO, O_RDWR); + + if (fd < 0) + { + fprintf(stderr, "open dhcpv6 server restart fifo when writing.\n"); + return 1; + } + write( fd, str, sizeof(str) ); + close(fd); + + #endif + return 0; +} + +void +WanMgr_DmlDhcpv6Remove(ANSC_HANDLE hContext) +{ + UNREFERENCED_PARAMETER(hContext); + /*remove backend memory*/ + if (g_sent_options) + AnscFreeMemory(g_sent_options); + return; +} + +int dhcpv6_assign_global_ip(char * prefix, char * intfName, char * ipAddr) +{ + unsigned int length = 0; + char globalIP[64] = {0}; + char *pMac = NULL; + unsigned int prefixLen = 0; + unsigned int iteratorI,iteratorJ = 0; + char cmd[256] = {0}; + char out[256] = {0}; + char tmp[8] = {0}; + + + _ansc_strcpy( globalIP, prefix); + + /* Prepare the first part. */ + + prefixLen = _ansc_strlen(globalIP); + + while( (globalIP[prefixLen-1] != '/') && (prefixLen>0) ) prefixLen--; + + if ( prefixLen == 0 ){ + AnscTrace("error, there is not '/' in prefix:%s\n", prefix); + return 1; + } + + length = atoi(&globalIP[prefixLen]); + + if ( length > 64 ){ + AnscTrace("error, length is bigger than 64. prefix:%s, length:%d\n", prefix, length); + return 1; + } + + globalIP[prefixLen-1] = '\0'; + + prefixLen = prefixLen-1; + + if ( (globalIP[prefixLen-1]!=':') && (globalIP[prefixLen-2]!=':') ){ + AnscTrace("error, there is not '::' in prefix:%s\n", prefix); + return 1; + } + + iteratorI = prefixLen-2; + iteratorJ = 0; + while( iteratorI > 0 ){ + if ( globalIP[iteratorI-1] == ':' ) + iteratorJ++; + iteratorI--; + } + + if ( iteratorJ == 3 ) + { + globalIP[prefixLen-1] = '\0'; + prefixLen = prefixLen - 1; + } + + AnscTrace("the first part is:%s\n", globalIP); + + + /* prepare second part */ + _ansc_sprintf(cmd, "ifconfig %s | grep HWaddr\n", intfName ); + _get_shell_output(cmd, out, sizeof(out)); + pMac =_ansc_strstr(out, "HWaddr"); + if ( pMac == NULL ){ + AnscTrace("error, this interface has not a mac address .\n"); + return 1; + } + + pMac += _ansc_strlen("HWaddr"); + while( pMac && (pMac[0] == ' ') ) + pMac++; + + /* switch 7bit to 1*/ + tmp[0] = pMac[1]; + + iteratorJ = strtol(tmp, (char **)NULL, 16); + + iteratorJ = iteratorJ ^ 0x2; + if ( iteratorJ < 10 ) + iteratorJ += '0'; + else + iteratorJ += 'A' - 10; + + pMac[1] = iteratorJ; + pMac[17] = '\0'; + + //00:50:56: FF:FE: 92:00:22 + _ansc_strncpy(out, pMac, 9); + out[9] = '\0'; + _ansc_strcat(out, "FF:FE:"); + _ansc_strcat(out, pMac+9); + + for(iteratorJ=0,iteratorI=0; out[iteratorI]; iteratorI++){ + if ( out[iteratorI] == ':' ) + continue; + globalIP[prefixLen++] = out[iteratorI]; + if ( ++iteratorJ == 4 ){ + globalIP[prefixLen++] = ':'; + iteratorJ = 0; + } + } + + globalIP[prefixLen-1] = '\0'; + + AnscTrace("the full part is:%s\n", globalIP); + + _ansc_strcpy(ipAddr, globalIP); + + /* This IP should be unique. If not I have no idea. */ + return 0; +} + +#define POS_PREFIX_DELEGATION 7 +int CalcIPv6Prefix(char *GlobalPref, char *pref,int index) +{ + unsigned char buf[sizeof(struct in6_addr)]; + int domain, s; + char str[INET6_ADDRSTRLEN]; + domain = AF_INET6; + s = inet_pton(domain, GlobalPref, buf); + if (s <= 0) { + if (s == 0) + fprintf(stderr, "Not in presentation format"); + else + perror("inet_pton"); + return 0; + } + buf[POS_PREFIX_DELEGATION] = buf[POS_PREFIX_DELEGATION] + index; + if (inet_ntop(domain, buf, str, INET6_ADDRSTRLEN) == NULL) { + perror("inet_ntop"); + return 0; + } + printf("%s\n", str); + strcpy(pref,str); + return 1; +} + +int GenIPv6Prefix(char *ifName,char *GlobalPref, char *pref) +{ +int len = 0; +int index = 0; +char cmd[100]; +char out[100]; +static int interface_num = 4; // Reserving first 4 /64s for dhcp configurations + if(ifName == NULL) + return 0; + + memset(cmd,0,sizeof(cmd)); + memset(out,0,sizeof(out)); + _ansc_sprintf(cmd, "%s%s",ifName,"_ipv6_index"); + sysevent_get(sysevent_fd, sysevent_token,cmd, out, sizeof(out)); + if(strlen(out) != 0) + { + index = atoi(out); + } + + len = strlen(GlobalPref); + strcpy(pref,GlobalPref); + if(index == 0) + { + if(CalcIPv6Prefix(GlobalPref,pref,interface_num)== 0) + return 0; + memset(cmd,0,sizeof(cmd)); + _ansc_sprintf(cmd, "%s%s",ifName,"_ipv6_index"); + _ansc_sprintf(out, "%d",interface_num); + sysevent_set(sysevent_fd, sysevent_token, cmd, out , 0); + interface_num++; + } + else + { + if(CalcIPv6Prefix(GlobalPref,pref,index)==0 ) + return 0; + } + strcat(pref,"/64"); + CcspTraceInfo(("%s: pref %s\n", __func__, pref)); +return 1; + +} +/* This thread is added to handle the LnF interface IPv6 rule, because LnF is coming up late in XB6 devices. +This thread can be generic to handle the operations depending on the interfaces. Other interface and their events can be register here later based on requirement */ +static int sysevent_fd_1; +static token_t sysevent_token_1; +static pthread_t InfEvtHandle_tid; +static void *InterfaceEventHandler_thrd(void *data) +{ + UNREFERENCED_PARAMETER(data); + async_id_t interface_asyncid; + async_id_t interface_XHS_asyncid; + + CcspTraceWarning(("%s started\n",__FUNCTION__)); + sysevent_fd_1 = sysevent_open("127.0.0.1", SE_SERVER_WELL_KNOWN_PORT, SE_VERSION, "Interface_evt_handler", &sysevent_token_1); + + sysevent_set_options(sysevent_fd_1, sysevent_token_1, "multinet_6-status", TUPLE_FLAG_EVENT); + sysevent_setnotification(sysevent_fd_1, sysevent_token_1, "multinet_6-status", &interface_asyncid); + sysevent_set_options(sysevent_fd_1, sysevent_token_1, "multinet_2-status", TUPLE_FLAG_EVENT); + sysevent_setnotification(sysevent_fd_1, sysevent_token_1, "multinet_2-status", &interface_XHS_asyncid); + while(1) + { + async_id_t getnotification_asyncid; + int err; + unsigned char name[25], val[42],buf[128],cmd[128]; + int namelen = sizeof(name); + int vallen = sizeof(val); + err = sysevent_getnotification(sysevent_fd_1, sysevent_token_1, name, &namelen, val, &vallen, &getnotification_asyncid); + + if (err) + { + CcspTraceWarning(("sysevent_getnotification failed with error: %d %s\n", err,__FUNCTION__)); + CcspTraceWarning(("sysevent_getnotification failed name: %s val : %s\n", name,val)); + if ( 0 != system("pidof syseventd")) { + + CcspTraceWarning(("%s syseventd not running ,breaking the receive notification loop \n",__FUNCTION__)); + break; + } + } + else + { + + CcspTraceWarning(("%s Recieved notification event %s\n",__FUNCTION__,name)); + if(strcmp((const char*)name,"multinet_6-status") == 0) + { + if(strcmp((const char*)val, "ready") == 0) + { + sysevent_get(sysevent_fd, sysevent_token,"br106_ipaddr_v6", buf, sizeof(buf)); + memset(cmd,0,sizeof(cmd)); + _ansc_sprintf(cmd, "ip -6 route add %s dev br106",buf); + system(cmd); + #ifdef _COSA_INTEL_XB3_ARM_ + memset(cmd,0,sizeof(cmd)); + _ansc_sprintf(cmd, "ip -6 route add %s dev br106 table erouter",buf); + system(cmd); + #endif + memset(cmd,0,sizeof(cmd)); + sprintf(cmd, "ip -6 rule add iif br106 lookup erouter"); + system(cmd); + } + + } + if(strcmp((const char*)name,"multinet_2-status") == 0) + { + if(strcmp((const char*)val, "ready") == 0) + { + char *Inf_name = NULL; + int retPsmGet = CCSP_SUCCESS; + retPsmGet = PSM_Get_Record_Value2(bus_handle,g_Subsystem, "dmsb.l2net.2.Port.1.Name", NULL, &Inf_name); + if (retPsmGet == CCSP_SUCCESS) + { + char tbuff[100]; + memset(cmd,0,sizeof(cmd)); + memset(tbuff,0,sizeof(tbuff)); + sprintf(cmd,"sysctl net.ipv6.conf.%s.autoconf",Inf_name); + _get_shell_output(cmd, tbuff, sizeof(tbuff)); + if(tbuff[strlen(tbuff)-1] == '0') + { + memset(cmd,0,sizeof(cmd)); + sprintf(cmd,"sysctl -w net.ipv6.conf.%s.autoconf=1",Inf_name); + system(cmd); + memset(cmd,0,sizeof(cmd)); + sprintf(cmd,"ifconfig %s down;ifconfig %s up",Inf_name,Inf_name); + system(cmd); + } + + memset(cmd,0,sizeof(cmd)); + _ansc_sprintf(cmd, "%s_ipaddr_v6",Inf_name); + sysevent_get(sysevent_fd, sysevent_token,cmd, buf, sizeof(buf)); + memset(cmd,0,sizeof(cmd)); + _ansc_sprintf(cmd, "ip -6 route add %s dev %s",buf,Inf_name); + system(cmd); + #ifdef _COSA_INTEL_XB3_ARM_ + memset(cmd,0,sizeof(cmd)); + _ansc_sprintf(cmd, "ip -6 route add %s dev %s table erouter",buf,Inf_name); + system(cmd); + #endif + memset(cmd,0,sizeof(cmd)); + sprintf(cmd, "ip -6 rule add iif %s lookup erouter",Inf_name); + system(cmd); + ((CCSP_MESSAGE_BUS_INFO *)bus_handle)->freefunc(Inf_name); + } + else + { + CcspTraceWarning(("%s PSM get failed for interface name\n", __FUNCTION__)); + } + } + + } + + } + } + +} +static int sysevent_fd_global = 0; +static token_t sysevent_token_global; + +static void * +dhcpv6c_dbg_thrd(void * in) +{ + UNREFERENCED_PARAMETER(in); + int fd=0 , fd1=0; + char msg[1024] = {0}; + int i; + char * p = NULL; + char globalIP2[128] = {0}; + char out[128] = {0}; + //When PaM restart, this is to get previous addr. + sysevent_get(sysevent_fd, sysevent_token,"lan_ipaddr_v6", globalIP2, sizeof(globalIP2)); + if ( globalIP2[0] ) + CcspTraceWarning((stderr,"%s It seems there is old value(%s)\n", __FUNCTION__, globalIP2)); + + sysevent_fd_global = sysevent_open("127.0.0.1", SE_SERVER_WELL_KNOWN_PORT, SE_VERSION, "Multinet Status", &sysevent_token_global); + + CcspTraceWarning(("%s sysevent_fd_global is %d\n", __FUNCTION__, sysevent_fd_global)); + + unsigned char lan_multinet_state[16] ; + + int return_val=0; + + fd_set rfds; + struct timeval tm; + + fd= open(CCSP_COMMON_FIFO, O_RDWR); + + if (fd< 0) + { + fprintf(stderr,"open common fifo!!!!!!!!!!!!\n"); + goto EXIT; + } + + while (1) + { + int retCode = 0; + tm.tv_sec = 60; + tm.tv_usec = 0; + + FD_ZERO(&rfds); + FD_SET(fd, &rfds); + retCode = select( (fd+1), &rfds, NULL, NULL, &tm); + /* When return -1, it's error. + When return 0, it's timeout + When return >0, it's the number of valid fds */ + if (retCode < 0) { + fprintf(stderr, "dbg_thrd : select returns error \n" ); + + if (errno == EINTR) + continue; + + CcspTraceWarning(("%s -- select(): %s", __FUNCTION__, strerror(errno))); + goto EXIT; + } + else if(retCode == 0 ) + continue; + if ( FD_ISSET(fd, &rfds) ) + { + memset(msg, 0, sizeof(msg)); + read(fd, msg, sizeof(msg)); + + } + else + continue; + + if (msg[0] != 0) + { + CcspTraceInfo(("%s: get message %s\n", __func__, msg)); + } else { + //Message is empty. Wait 5 sec before trying the select again. + sleep(5); + continue; + } + + if (!strncmp(msg, "dibbler-client", strlen("dibbler-client"))) + { + char v6addr[64] = {0}; + char v6pref[128] = {0}; + char v6pref_addr[128] = {0}; + char v6Tpref[128] = {0}; + int pref_len = 0; + + char iana_t1[32] = {0}; + char iana_t2[32] = {0}; + char iana_iaid[32] = {0}; + char iana_pretm[32] = {0}; + char iana_vldtm[32] = {0}; + + char iapd_t1[32] = {0}; + char iapd_t2[32] = {0}; + char iapd_iaid[32] = {0}; + char iapd_pretm[32] = {0}; + char iapd_vldtm[32] = {0}; + + int t1 = 0; + int idx = 0; + char action[64] = {0}; + char objName[128] = {0}; + char globalIP[128] = {0}; + BOOL bRestartLan = FALSE; + int ret = 0; +#ifdef _HUB4_PRODUCT_REQ_ + char ula_address[64] = {0}; +#endif + /*the format is : + add 2000::ba7a:1ed4:99ea:cd9f :: 0 t1 + action, address, prefix, pref_len 3600 + now action only supports "add", "del"*/ + + p = msg+strlen("dibbler-client"); + while(isblank(*p)) p++; + + fprintf(stderr, "%s -- %d !!! get event from v6 client: %s \n", __FUNCTION__, __LINE__,p); + + if (sscanf(p, "%63s %63s %s %s %s %s %s %63s %d %s %s %s %s %s", + action, v6addr, iana_iaid, iana_t1, iana_t2, iana_pretm, iana_vldtm, + v6pref, &pref_len, iapd_iaid, iapd_t1, iapd_t2, iapd_pretm, iapd_vldtm ) == 14) + { + if (!strncmp(action, "add", 3)) + { + CcspTraceInfo(("%s: add\n", __func__)); + +// Waiting until private lan interface is ready , so that we can assign global ipv6 address and also start dhcp server. + while (1) + { + + memset(lan_multinet_state,0,sizeof(lan_multinet_state)); + return_val=sysevent_get(sysevent_fd_global, sysevent_token_global, "multinet_1-status", lan_multinet_state, sizeof(lan_multinet_state)); + + CcspTraceWarning(("%s multinet_1-status is %s, ret val is %d\n",__FUNCTION__,lan_multinet_state,return_val)); + + if(strcmp((const char*)lan_multinet_state, "ready") == 0) + { + break; + } + + sleep(5); + } + + /*for now we only support one address, one prefix notify, if need multiple addr/prefix, must modify dibbler-client code*/ + if (strncmp(v6addr, "::", 2) != 0) + { + sysevent_set(sysevent_fd, sysevent_token, COSA_DML_DHCPV6C_ADDR_SYSEVENT_NAME, v6addr , 0); + sysevent_set(sysevent_fd, sysevent_token, COSA_DML_DHCPV6C_ADDR_IAID_SYSEVENT_NAME, iana_iaid , 0); + sysevent_set(sysevent_fd, sysevent_token, COSA_DML_DHCPV6C_ADDR_T1_SYSEVENT_NAME, iana_t1 , 0); + sysevent_set(sysevent_fd, sysevent_token, COSA_DML_DHCPV6C_ADDR_T2_SYSEVENT_NAME, iana_t2 , 0); + sysevent_set(sysevent_fd, sysevent_token, COSA_DML_DHCPV6C_ADDR_PRETM_SYSEVENT_NAME, iana_pretm , 0); + sysevent_set(sysevent_fd, sysevent_token, COSA_DML_DHCPV6C_ADDR_VLDTM_SYSEVENT_NAME, iana_vldtm , 0); + } + + if (strncmp(v6pref, "::", 2) != 0) + { + memset(v6Tpref,0,sizeof(v6Tpref)); + strncpy(v6Tpref,v6pref,sizeof(v6Tpref)); + /*We just delegate longer and equal 64bits. Use zero to fill in the slot naturally. */ +#if defined (MULTILAN_FEATURE) + sprintf(v6pref+strlen(v6pref), "/%d", pref_len); +#else + if ( pref_len >= 64 ) + sprintf(v6pref+strlen(v6pref), "/%d", pref_len); + else + { +#if defined(CISCO_CONFIG_DHCPV6_PREFIX_DELEGATION) + sprintf(v6pref+strlen(v6pref), "/%d", pref_len); +#else + sprintf(v6pref+strlen(v6pref), "/%d", 64); +#endif + } +#endif + char cmd[100]; +#if defined(CISCO_CONFIG_DHCPV6_PREFIX_DELEGATION) && defined(_CBR_PRODUCT_REQ_) +#else + char out1[100]; + char *token = NULL;char *pt; + char s[2] = ","; + if(pref_len < 64) + { + memset(out,0,sizeof(out)); + memset(cmd,0,sizeof(cmd)); + memset(out1,0,sizeof(out1)); + sprintf(cmd, "syscfg get IPv6subPrefix"); + _get_shell_output(cmd, out, sizeof(out)); + if(!strcmp(out,"true")) + { + static int first = 0; + + memset(out,0,sizeof(out)); + memset(cmd,0,sizeof(cmd)); + sprintf(cmd, "syscfg get IPv6_Interface"); + _get_shell_output(cmd, out, sizeof(out)); + pt = out; + while((token = strtok_r(pt, ",", &pt))) + { + + if(GenIPv6Prefix(token,v6Tpref,out1)) + { + char tbuff[100]; + memset(cmd,0,sizeof(cmd)); + _ansc_sprintf(cmd, "%s%s",token,"_ipaddr_v6"); + sysevent_set(sysevent_fd, sysevent_token, cmd, out1 , 0); + memset(cmd,0,sizeof(cmd)); + memset(tbuff,0,sizeof(tbuff)); + sprintf(cmd,"sysctl net.ipv6.conf.%s.autoconf",token); + _get_shell_output(cmd, tbuff, sizeof(tbuff)); + if(tbuff[strlen(tbuff)-1] == '0') + { + memset(cmd,0,sizeof(cmd)); + sprintf(cmd,"sysctl -w net.ipv6.conf.%s.autoconf=1",token); + system(cmd); + memset(cmd,0,sizeof(cmd)); + sprintf(cmd,"ifconfig %s down;ifconfig %s up",token,token); + system(cmd); + } + memset(cmd,0,sizeof(cmd)); + sprintf(cmd, "ip -6 route add %s dev %s", out1, token); + system(cmd); + #ifdef _COSA_INTEL_XB3_ARM_ + memset(cmd,0,sizeof(cmd)); + sprintf(cmd, "ip -6 route add %s dev %s table erouter", out1, token); + system(cmd); + #endif + memset(cmd,0,sizeof(cmd)); + sprintf(cmd, "ip -6 rule add iif %s lookup erouter",token); + system(cmd); + memset(out1,0,sizeof(out1)); + } + } + memset(out,0,sizeof(out)); + if(first == 0) + { first = 1; + pthread_create(&InfEvtHandle_tid, NULL, InterfaceEventHandler_thrd, NULL); + } + } + } +#endif + + sysevent_set(sysevent_fd, sysevent_token,COSA_DML_DHCPV6C_PREF_SYSEVENT_NAME, v6pref , 0); + sysevent_set(sysevent_fd, sysevent_token,COSA_DML_DHCPV6C_PREF_IAID_SYSEVENT_NAME, iapd_iaid , 0); + sysevent_set(sysevent_fd, sysevent_token,COSA_DML_DHCPV6C_PREF_IAID_SYSEVENT_NAME, iapd_iaid , 0); + sysevent_set(sysevent_fd, sysevent_token,COSA_DML_DHCPV6C_PREF_T1_SYSEVENT_NAME, iapd_t1 , 0); + sysevent_set(sysevent_fd, sysevent_token,COSA_DML_DHCPV6C_PREF_T2_SYSEVENT_NAME, iapd_t2 , 0); + sysevent_set(sysevent_fd, sysevent_token,COSA_DML_DHCPV6C_PREF_PRETM_SYSEVENT_NAME, iapd_pretm , 0); + sysevent_set(sysevent_fd, sysevent_token,COSA_DML_DHCPV6C_PREF_VLDTM_SYSEVENT_NAME, iapd_vldtm , 0); + + +#if defined (MULTILAN_FEATURE) + if ((v6addr_prev[0] == '\0') || ( _ansc_strcmp(v6addr_prev, v6pref ) !=0)) + { + _ansc_strncpy( v6addr_prev, v6pref, sizeof(v6pref)); + sysevent_set(sysevent_fd, sysevent_token,"ipv6-restart", "1", 0); + } + else + { + sysevent_set(sysevent_fd, sysevent_token,"ipv6_addr-set", "", 0); + } +#endif + +#ifdef MULTILAN_FEATURE +/* Service IPv6 will assign IP address and prefix allocation, + for all lan interfaces. +*/ +#if !defined(INTEL_PUMA7) && !defined(_COSA_INTEL_XB3_ARM_) + // not the best place to add route, just to make it work + // delegated prefix need to route to LAN interface + memset(cmd,0,sizeof(cmd)); + sprintf(cmd, "ip -6 route add %s dev %s", v6pref, COSA_DML_DHCPV6_SERVER_IFNAME); + system(cmd); + #ifdef _COSA_INTEL_XB3_ARM_ + memset(cmd,0,sizeof(cmd)); + sprintf(cmd, "ip -6 route add %s dev %s table erouter", v6pref, COSA_DML_DHCPV6_SERVER_IFNAME); + system(cmd); + #endif + memset(cmd,0,sizeof(cmd)); + /* we need save this for zebra to send RA + ipv6_prefix // xx:xx::/yy + */ + sprintf(cmd, "sysevent set ipv6_prefix %s \n",v6pref); + system(cmd); + CcspTraceWarning(("!run cmd1:%s", cmd)); + + DHCPv6sDmlTriggerRestart(FALSE); +#if defined(_COSA_BCM_ARM_) || defined(INTEL_PUMA7) + CcspTraceWarning((" %s dhcpv6_assign_global_ip to brlan0 \n", __FUNCTION__)); + ret = dhcpv6_assign_global_ip(v6pref, "brlan0", globalIP); +#elif defined _COSA_BCM_MIPS_ + ret = dhcpv6_assign_global_ip(v6pref, COSA_DML_DHCPV6_SERVER_IFNAME, globalIP); +#else + /*We need get a global ip addres */ + ret = dhcpv6_assign_global_ip(v6pref, "l2sd0", globalIP); +#endif + CcspTraceWarning(("%s: globalIP %s globalIP2 %s\n", __func__, + globalIP, globalIP2)); + if ( _ansc_strcmp(globalIP, globalIP2 ) ){ + bRestartLan = TRUE; + + //PaM may restart. When this happen, we should not overwrite previous ipv6 + if ( globalIP2[0] ) + sysevent_set(sysevent_fd, sysevent_token,"lan_ipaddr_v6_prev", globalIP2, 0); + + _ansc_strcpy(globalIP2, globalIP); + }else{ + char lanrestart[8] = {0}; + sysevent_get(sysevent_fd, sysevent_token,"lan_restarted",lanrestart, sizeof(lanrestart)); + fprintf(stderr,"lan restart staus is %s \n",lanrestart); + if (strcmp("true",lanrestart) == 0) + bRestartLan = TRUE; + else + bRestartLan = FALSE; + } + CcspTraceWarning(("%s: bRestartLan %d\n", __func__, bRestartLan)); + + fprintf(stderr, "%s -- %d !!! ret:%d bRestartLan:%d %s %s \n", __FUNCTION__, __LINE__,ret, bRestartLan, globalIP, globalIP2); + + if ( ret != 0 ) + { + AnscTrace("error, assign global ip error.\n"); + }else if ( bRestartLan == FALSE ){ + AnscTrace("Same global IP, Need not restart.\n"); + }else{ + /* This is for IP.Interface.1. use */ + sysevent_set(sysevent_fd, sysevent_token,COSA_DML_DHCPV6S_ADDR_SYSEVENT_NAME, globalIP, 0); + + /*This is for brlan0 interface */ + sysevent_set(sysevent_fd, sysevent_token,"lan_ipaddr_v6", globalIP, 0); + _ansc_sprintf(cmd, "%d", pref_len); + sysevent_set(sysevent_fd, sysevent_token,"lan_prefix_v6", cmd, 0); + + sysevent_set(sysevent_fd, sysevent_token,"lan-restart", "1", 0); + } +#endif +#else +#ifdef _HUB4_PRODUCT_REQ_ + if ((iapd_vldtm[0]=='\0') || (iapd_pretm[0]=='\0')){ + strncpy(iapd_pretm, "forever", sizeof(iapd_pretm)); + strncpy(iapd_vldtm, "forever", sizeof(iapd_vldtm)); + } + sysevent_get(sysevent_fd, sysevent_token,SYSEVENT_FIELD_IPV6_ULA_ADDRESS, ula_address, sizeof(ula_address)); + if(ula_address[0] != '\0') { + sprintf(cmd, "ip -6 addr add %s/64 dev %s", ula_address, COSA_DML_DHCPV6_SERVER_IFNAME); + system(cmd); + } + ret = dhcpv6_assign_global_ip(v6pref, COSA_DML_DHCPV6_SERVER_IFNAME, globalIP); + if(ret != 0) { + CcspTraceInfo(("Assign global ip error \n")); + } + else { + sysevent_set(sysevent_fd, sysevent_token,"lan_ipaddr_v6", globalIP, 0); + sprintf(cmd, "ip -6 addr add %s/64 dev %s valid_lft %s preferred_lft %s", + globalIP, COSA_DML_DHCPV6_SERVER_IFNAME, iapd_vldtm, iapd_pretm); + CcspTraceInfo(("Going to execute: %s \n", cmd)); + system(cmd); + } + if(strlen(v6pref) > 0) { + strncpy(v6pref_addr, v6pref, (strlen(v6pref)-5)); + CcspTraceInfo(("Going to set ::1 address on brlan0 interface \n")); + sprintf(cmd, "ip -6 addr add %s::1/64 dev %s valid_lft %s preferred_lft %s", + v6pref_addr, COSA_DML_DHCPV6_SERVER_IFNAME, iapd_vldtm, iapd_pretm); + CcspTraceInfo(("Going to execute: %s \n", cmd)); + system(cmd); + } + // send an event to Sky-pro app manager that Global-prefix is set + sysevent_set(sysevent_fd, sysevent_token,"lan_prefix_set", globalIP, 0); + /** + * Send data to wanmanager. + */ + int ipv6_wan_status = 0; + char dns_server[256] = {'\0'}; + unsigned int prefix_pref_time = 0; + unsigned int prefix_valid_time = 0; + char c; + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceDataByName_locked(PHY_WAN_IF_NAME); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pIfaceData = &(pWanDmlIfaceData->data); + if(pIfaceData->IP.pIpcIpv6Data == NULL) + { + pIfaceData->IP.pIpcIpv6Data = (ipc_dhcpv6_data_t*) malloc(sizeof(ipc_dhcpv6_data_t)); + if(pIfaceData->IP.pIpcIpv6Data != NULL) + { + strncpy(pIfaceData->IP.pIpcIpv6Data->ifname, pIfaceData->Wan.Name, sizeof(pIfaceData->IP.pIpcIpv6Data->ifname)); + if(strlen(v6pref) == 0) + { + pIfaceData->IP.pIpcIpv6Data->isExpired = TRUE; + } + else + { + pIfaceData->IP.pIpcIpv6Data->isExpired = FALSE; + pIfaceData->IP.pIpcIpv6Data->prefixAssigned = TRUE; + strncpy(pIfaceData->IP.pIpcIpv6Data->sitePrefix, v6pref, sizeof(pIfaceData->IP.pIpcIpv6Data->sitePrefix)); + strncpy(pIfaceData->IP.pIpcIpv6Data->pdIfAddress, "", sizeof(pIfaceData->IP.pIpcIpv6Data->pdIfAddress)); + /** DNS servers. **/ + sysevent_get(sysevent_fd, sysevent_token,SYSEVENT_FIELD_IPV6_DNS_SERVER, dns_server, sizeof(dns_server)); + if (strlen(dns_server) != 0) + { + pIfaceData->IP.pIpcIpv6Data->dnsAssigned = TRUE; + sscanf (dns_server, "%s %s", pIfaceData->IP.pIpcIpv6Data->nameserver, + pIfaceData->IP.pIpcIpv6Data->nameserver1); + } + sscanf(iapd_pretm, "%c%u%c", &c, &prefix_pref_time, &c); + sscanf(iapd_vldtm, "%c%u%c", &c, &prefix_valid_time, &c); + pIfaceData->IP.pIpcIpv6Data->prefixPltime = prefix_pref_time; + pIfaceData->IP.pIpcIpv6Data->prefixVltime = prefix_valid_time; + pIfaceData->IP.pIpcIpv6Data->maptAssigned = FALSE; + pIfaceData->IP.pIpcIpv6Data->mapeAssigned = FALSE; + pIfaceData->IP.pIpcIpv6Data->prefixCmd = 0; + } + if (wanmgr_handle_dchpv6_event_data(pIfaceData) != ANSC_STATUS_SUCCESS) + { + CcspTraceError(("[%s-%d] Failed to send dhcpv6 data to wanmanager!!! \n", __FUNCTION__, __LINE__)); + } + } + } + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } +#endif + // not the best place to add route, just to make it work + // delegated prefix need to route to LAN interface + sprintf(cmd, "ip -6 route add %s dev %s", v6pref, COSA_DML_DHCPV6_SERVER_IFNAME); + system(cmd); + #ifdef _COSA_INTEL_XB3_ARM_ + memset(cmd,0,sizeof(cmd)); + sprintf(cmd, "ip -6 route add %s dev %s table erouter", v6pref, COSA_DML_DHCPV6_SERVER_IFNAME); + system(cmd); + #endif + /* we need save this for zebra to send RA + ipv6_prefix // xx:xx::/yy + */ +#ifndef _HUB4_PRODUCT_REQ_ + sprintf(cmd, "sysevent set ipv6_prefix %s \n",v6pref); + system(cmd); +#else + sprintf(cmd, "sysevent set zebra-restart \n"); + system(cmd); +#endif + CcspTraceWarning(("!run cmd1:%s", cmd)); + + DHCPv6sDmlTriggerRestart(FALSE); + + /*We need get a global ip addres */ +#if defined(_COSA_BCM_ARM_) || defined(INTEL_PUMA7) + /*this is for tchxb6*/ + CcspTraceWarning((" %s dhcpv6_assign_global_ip to brlan0 \n", __FUNCTION__)); + ret = dhcpv6_assign_global_ip(v6pref, "brlan0", globalIP); +#elif defined _COSA_BCM_MIPS_ + ret = dhcpv6_assign_global_ip(v6pref, COSA_DML_DHCPV6_SERVER_IFNAME, globalIP); +#else + ret = dhcpv6_assign_global_ip(v6pref, "l2sd0", globalIP); +#endif + CcspTraceWarning(("%s: globalIP %s globalIP2 %s\n", __func__, + globalIP, globalIP2)); + if ( _ansc_strcmp(globalIP, globalIP2 ) ){ + bRestartLan = TRUE; + + //PaM may restart. When this happen, we should not overwrite previous ipv6 + if ( globalIP2[0] ) + sysevent_set(sysevent_fd, sysevent_token,"lan_ipaddr_v6_prev", globalIP2, 0); + + _ansc_strcpy(globalIP2, globalIP); + }else{ + char lanrestart[8] = {0}; + sysevent_get(sysevent_fd, sysevent_token,"lan_restarted",lanrestart, sizeof(lanrestart)); + fprintf(stderr,"lan restart staus is %s \n",lanrestart); + if (strcmp("true",lanrestart) == 0) + bRestartLan = TRUE; + else + bRestartLan = FALSE; + } + CcspTraceWarning(("%s: bRestartLan %d\n", __func__, bRestartLan)); + + fprintf(stderr, "%s -- %d !!! ret:%d bRestartLan:%d %s %s \n", __FUNCTION__, __LINE__,ret, bRestartLan, globalIP, globalIP2); + + if ( ret != 0 ) + { + AnscTrace("error, assign global ip error.\n"); + }else if ( bRestartLan == FALSE ){ + AnscTrace("Same global IP, Need not restart.\n"); + }else{ + /* This is for IP.Interface.1. use */ + sysevent_set(sysevent_fd, sysevent_token,COSA_DML_DHCPV6S_ADDR_SYSEVENT_NAME, globalIP, 0); + + /*This is for brlan0 interface */ + sysevent_set(sysevent_fd, sysevent_token,"lan_ipaddr_v6", globalIP, 0); + _ansc_sprintf(cmd, "%d", pref_len); + sysevent_set(sysevent_fd, sysevent_token,"lan_prefix_v6", cmd, 0); + + sysevent_set(sysevent_fd, sysevent_token,"lan-restart", "1", 0); + } +#endif + } + } + else if (!strncmp(action, "del", 3)) + { + /*todo*/ + } +#if defined(CISCO_CONFIG_DHCPV6_PREFIX_DELEGATION) && (defined(_CBR_PRODUCT_REQ_) || defined(_BCI_FEATURE_REQ)) + +#else + system("sysevent set zebra-restart"); +#endif + } + + } +#ifdef _DEBUG + else if (!strncmp(msg, "mem", 3)) + { + /*add the test funcs in the run time.*/ + + AnscTraceMemoryTable(); + } +#endif + } + +EXIT: + if(fd>=0) { + close(fd); + } + + if(fd1>=0) { + close(fd1); + } + + return NULL; +} + + + +static ANSC_STATUS wanmgr_dchpv6_get_ipc_msg_info(WANMGR_IPV6_DATA* pDhcpv6Data, ipc_dhcpv6_data_t* pIpcIpv6Data) +{ + if((pDhcpv6Data == NULL) || (pIpcIpv6Data == NULL)) + { + return ANSC_STATUS_FAILURE; + } + memcpy(pDhcpv6Data->ifname, pIpcIpv6Data->ifname, BUFLEN_32); + memcpy(pDhcpv6Data->address, pIpcIpv6Data->address, BUFLEN_48); + memcpy(pDhcpv6Data->pdIfAddress, pIpcIpv6Data->pdIfAddress, BUFLEN_48); + memcpy(pDhcpv6Data->nameserver, pIpcIpv6Data->nameserver, BUFLEN_128); + memcpy(pDhcpv6Data->nameserver1, pIpcIpv6Data->nameserver1, BUFLEN_128); + memcpy(pDhcpv6Data->domainName, pIpcIpv6Data->domainName, BUFLEN_64); + memcpy(pDhcpv6Data->sitePrefix, pIpcIpv6Data->sitePrefix, BUFLEN_48); + pDhcpv6Data->prefixPltime = pIpcIpv6Data->prefixPltime; + pDhcpv6Data->prefixVltime = pIpcIpv6Data->prefixVltime; + memcpy(pDhcpv6Data->sitePrefixOld, pIpcIpv6Data->sitePrefixOld, BUFLEN_48); + + return ANSC_STATUS_SUCCESS; +} + +ANSC_STATUS wanmgr_handle_dchpv6_event_data(DML_WAN_IFACE* pIfaceData) +{ + if(NULL == pIfaceData) + { + return ANSC_STATUS_FAILURE; + } + + ipc_dhcpv6_data_t* pNewIpcMsg = pIfaceData->IP.pIpcIpv6Data; + WANMGR_IPV6_DATA* pDhcp6cInfoCur = &(pIfaceData->IP.Ipv6Data); + if((NULL == pDhcp6cInfoCur) || (NULL == pNewIpcMsg)) + { + return ANSC_STATUS_BAD_PARAMETER; + } + + BOOL connected = FALSE; + char set_value[BUFLEN_64]; + + memset(set_value, 0, sizeof(set_value)); + + CcspTraceInfo(("prefixAssigned=%dprefixCmd=%dsitePrefix=%spdIfAddress=%sprefixPltime=%dprefixVltime=%d\n" + "addrAssigned=%daddrCmd=%daddress=%sifname=%s\n" + "maptAssigned=%d mapeAssigned=%d\n" + "dnsAssigned=%dnameserver=%s,%saftrAssigned=%daftr=%sisExpired=%d \n", + pNewIpcMsg->prefixAssigned, pNewIpcMsg->prefixCmd, pNewIpcMsg->sitePrefix, + pNewIpcMsg->pdIfAddress, pNewIpcMsg->prefixPltime, pNewIpcMsg->prefixVltime, + pNewIpcMsg->addrAssigned, pNewIpcMsg->addrCmd, pNewIpcMsg->address, pNewIpcMsg->ifname, + pNewIpcMsg->maptAssigned, pNewIpcMsg->mapeAssigned, + pNewIpcMsg->dnsAssigned, pNewIpcMsg->nameserver, pNewIpcMsg->nameserver1, pNewIpcMsg->aftrAssigned, pNewIpcMsg->aftr, pNewIpcMsg->isExpired)); + + + + /*Check lease expiry*/ + if (pNewIpcMsg->isExpired) + { + CcspTraceInfo(("DHCP6LeaseExpired\n")); + // update current IPv6 data + wanmgr_dchpv6_get_ipc_msg_info(&(pIfaceData->IP.Ipv6Data), pNewIpcMsg); + WanManager_UpdateInterfaceStatus(pIfaceData, WANMGR_IFACE_CONNECTION_IPV6_DOWN); + + //Free buffer + if (pIfaceData->IP.pIpcIpv6Data != NULL ) + { + //free memory + free(pIfaceData->IP.pIpcIpv6Data); + pIfaceData->IP.pIpcIpv6Data = NULL; + } + + return ANSC_STATUS_SUCCESS; + } + + +#ifdef FEATURE_MAPT + Dhcp6cMAPTParametersMsgBody dhcp6cMAPTMsgBodyPrvs; + size_t expectedLength = sizeof(ipc_dhcpv6_data_t) + sizeof(Dhcp6cMAPTParametersMsgBody); + CcspTraceNotice(("FEATURE_MAPT: MAP-T Enable %d\n", pNewIpcMsg->maptAssigned)); + if (pNewIpcMsg->maptAssigned && (msg->dataLength == expectedLength)) + { + Dhcp6cMAPTParametersMsgBody *dhcp6cMAPTMsgBody = (Dhcp6cMAPTParametersMsgBody *)(pNewIpcMsg + 1); +#ifdef FEATURE_MAPT_DEBUG + LOG_PRINT_MAPT("Got an event in Wanmanager for MAPT - CONFIG"); +#endif + //get MAP-T previous data + memcpy(&dhcp6cMAPTMsgBodyPrvs, &(pIfaceData->MAP.dhcp6cMAPTparameters), sizeof(Dhcp6cMAPTParametersMsgBody)); + + if (memcmp(dhcp6cMAPTMsgBody, &dhcp6cMAPTMsgBodyPrvs, sizeof(Dhcp6cMAPTParametersMsgBody)) != 0) + { + //WanManager_UpdateGlobalWanData(MAPT_CONFIG_CHANGED, TRUE); + pIfaceData->MAP.MaptChanged = TRUE; + } + + // store MAP-T parameters locally + memcpy(&(pIfaceData->MAP.dhcp6cMAPTparameters), dhcp6cMAPTMsgBody, sizeof(Dhcp6cMAPTParametersMsgBody)); + + // update MAP-T flags + WanManager_UpdateInterfaceStatus(pIfaceData, WANMGR_IFACE_MAPT_START); + } + else + { +#ifdef FEATURE_MAPT_DEBUG + LOG_PRINT_MAPT("Got an event in Wanmanager for MAPT - STOP"); +#endif + // reset MAP-T parameters + memset(&(pIfaceData->MAP.dhcp6cMAPTparameters), 0, sizeof(Dhcp6cMAPTParametersMsgBody)); + WanManager_UpdateInterfaceStatus(pIfaceData, WANMGR_IFACE_MAPT_STOP); + } +#endif // FEATURE_MAPT + + + /* dhcp6c receives an IPv6 address for WAN interface */ + if (pNewIpcMsg->addrAssigned) + { + if (pNewIpcMsg->addrCmd == IFADDRCONF_ADD) + { + CcspTraceInfo(("assigned IPv6 address \n")); + connected = TRUE; + if (strcmp(pDhcp6cInfoCur->address, pNewIpcMsg->address)) + { + syscfg_set_string(SYSCFG_FIELD_IPV6_ADDRESS, pNewIpcMsg->address); + } + } + else /* IFADDRCONF_REMOVE */ + { + CcspTraceInfo(("remove IPv6 address \n")); + syscfg_set_string(SYSCFG_FIELD_IPV6_ADDRESS, ""); + } + } + + /* dhcp6c receives prefix delegation for LAN */ + if (pNewIpcMsg->prefixAssigned && !IS_EMPTY_STRING(pNewIpcMsg->sitePrefix)) + { + if (pNewIpcMsg->prefixCmd == IFADDRCONF_ADD && + pNewIpcMsg->prefixPltime != 0 && pNewIpcMsg->prefixVltime != 0) + { + CcspTraceInfo(("assigned prefix=%s \n", pNewIpcMsg->sitePrefix)); + connected = TRUE; + + /* Update the WAN prefix validity time in the persistent storage */ + if (pDhcp6cInfoCur->prefixVltime != pNewIpcMsg->prefixVltime) + { + snprintf(set_value, sizeof(set_value), "%d", pNewIpcMsg->prefixVltime); + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_FIELD_IPV6_PREFIXVLTIME, set_value, 0); + } + + if (pDhcp6cInfoCur->prefixPltime != pNewIpcMsg->prefixPltime) + { + snprintf(set_value, sizeof(set_value), "%d", pNewIpcMsg->prefixPltime); + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_FIELD_IPV6_PREFIXPLTIME, set_value, 0); + } + + if (strcmp(pDhcp6cInfoCur->sitePrefixOld, pNewIpcMsg->sitePrefixOld)) + { + syscfg_set_string(SYSCFG_FIELD_PREVIOUS_IPV6_PREFIX, pNewIpcMsg->sitePrefixOld); + } + + if (strcmp(pDhcp6cInfoCur->sitePrefix, pNewIpcMsg->sitePrefix)) + { + syscfg_set_string(SYSCFG_FIELD_IPV6_PREFIX, pNewIpcMsg->sitePrefix); + } + + // create global IPv6 address (::1) + char prefix[BUFLEN_64] = {0}; + memset(prefix, 0, sizeof(prefix)); + + int index = strcspn(pNewIpcMsg->sitePrefix, "/"); + if (index < strlen(pNewIpcMsg->sitePrefix) && index < sizeof(prefix)) + { + strncpy(prefix, pNewIpcMsg->sitePrefix, index); // only copy prefix without the prefix length + snprintf(set_value, sizeof(set_value), "%s1", prefix); // concatenate "1" onto the prefix, which is in the form "xxxx:xxxx:xxxx:xxxx::" + snprintf(pNewIpcMsg->pdIfAddress, sizeof(pNewIpcMsg->pdIfAddress), "%s/64", set_value); // concatenate prefix address with length "/64" + + if (strcmp(pDhcp6cInfoCur->pdIfAddress, pNewIpcMsg->pdIfAddress)) + { + syscfg_set_string(SYSCFG_FIELD_IPV6_PREFIX_ADDRESS, pNewIpcMsg->pdIfAddress); + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_FIELD_TR_BRLAN0_DHCPV6_SERVER_ADDRESS, set_value, 0); + } + + if (strcmp(pDhcp6cInfoCur->sitePrefix, pNewIpcMsg->sitePrefix) != 0) + { + CcspTraceInfo(("%s %d new prefix = %s, current prefix = %s \n", __FUNCTION__, __LINE__, pNewIpcMsg->sitePrefix, pDhcp6cInfoCur->sitePrefix)); + strncat(prefix, "/64", 3); + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_FIELD_IPV6_PREFIX, prefix, 0); + } + } + } + else /* IFADDRCONF_REMOVE: prefix remove */ + { + /* Validate if the prefix to be removed is the same as the stored prefix */ + if (strcmp(pDhcp6cInfoCur->sitePrefix, pNewIpcMsg->sitePrefix) == 0) + { + CcspTraceInfo(("remove prefix \n")); + syscfg_set_string(SYSCFG_FIELD_IPV6_PREFIX, ""); + syscfg_set_string(SYSCFG_FIELD_PREVIOUS_IPV6_PREFIX, ""); + syscfg_set_string(SYSCFG_FIELD_IPV6_PREFIX_ADDRESS, ""); + WanManager_UpdateInterfaceStatus(pIfaceData, WANMGR_IFACE_CONNECTION_IPV6_DOWN); + } + } + } + + /* dhcp6c receives dns information */ + if (pNewIpcMsg->dnsAssigned) + { + if (!IS_EMPTY_STRING(pNewIpcMsg->nameserver)) + { + CcspTraceInfo(("assigned nameserver=%s", pNewIpcMsg->nameserver)); + + if (strcmp(pDhcp6cInfoCur->nameserver, pNewIpcMsg->nameserver)) + { + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_FIELD_IPV6_DNS_PRIMARY, pNewIpcMsg->nameserver, 0); + } + } + + if (!IS_EMPTY_STRING(pNewIpcMsg->nameserver1)) + { + CcspTraceInfo(("assigned nameserver=%s", pNewIpcMsg->nameserver1)); + + if (strcmp(pDhcp6cInfoCur->nameserver1, pNewIpcMsg->nameserver1)) + { + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_FIELD_IPV6_DNS_SECONDARY, pNewIpcMsg->nameserver1, 0); + } + } + } + + /* dhcp6c receives domain name information */ + if (pNewIpcMsg->domainNameAssigned && !IS_EMPTY_STRING(pNewIpcMsg->domainName)) + { + CcspTraceInfo(("assigned domain name=%s \n", pNewIpcMsg->domainName)); + + if (strcmp(pDhcp6cInfoCur->domainName, pNewIpcMsg->domainName)) + { + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_FIELD_IPV6_DOMAIN, pNewIpcMsg->domainName, 0); + } + } + + /* Even when dhcp6c is not used to get the WAN interface IP address, + * * use this message as a trigger to check the WAN interface IP. + * * Maybe we've been assigned an address by SLAAC.*/ + if (!pNewIpcMsg->addrAssigned) + { + char guAddr[IP_ADDR_LENGTH] = {0}; + char guAddrPrefix[IP_ADDR_LENGTH] = {0}; + uint32_t prefixLen = 0; + ANSC_STATUS r2; + + r2 = WanManager_getGloballyUniqueIfAddr6(pIfaceData->Wan.Name, guAddr, &prefixLen); + + if (ANSC_STATUS_SUCCESS == r2) + { + sprintf(guAddrPrefix, "%s/%d", guAddr, prefixLen); + CcspTraceInfo(("Detected GloballyUnique Addr6 %s, mark connection up! \n", guAddrPrefix)); + connected = TRUE; + + if (strcmp(pDhcp6cInfoCur->address, guAddrPrefix)) + { + syscfg_set_string(SYSCFG_FIELD_IPV6_ADDRESS, guAddrPrefix); + } + } + } + + /* + * dhcp6c receives AFTR information + * TODO: should we update aftr even WAN is not connected? + */ + if (connected && pNewIpcMsg->aftrAssigned && !IS_EMPTY_STRING(pNewIpcMsg->aftr)) + { + CcspTraceInfo(("assigned aftr=%s \n", pNewIpcMsg->aftr)); + } + + if (connected) + { + WANMGR_IPV6_DATA Ipv6DataTemp; + wanmgr_dchpv6_get_ipc_msg_info(&(Ipv6DataTemp), pNewIpcMsg); + + if (strcmp(Ipv6DataTemp.address, pDhcp6cInfoCur->address) || + strcmp(Ipv6DataTemp.pdIfAddress, pDhcp6cInfoCur->pdIfAddress) || + strcmp(Ipv6DataTemp.nameserver, pDhcp6cInfoCur->nameserver) || + strcmp(Ipv6DataTemp.nameserver1, pDhcp6cInfoCur->nameserver1) || + strcmp(Ipv6DataTemp.sitePrefix, pDhcp6cInfoCur->sitePrefix)) + { + CcspTraceInfo(("IPv6 configuration has been changed \n")); + pIfaceData->IP.Ipv6Changed = TRUE; + } + else + { + /*TODO: Revisit this*/ + //call function for changing the prlft and vallft + if ((WanManager_Ipv6AddrUtil(LAN_BRIDGE_NAME, SET_LFT, pNewIpcMsg->prefixPltime, pNewIpcMsg->prefixVltime) < 0)) + { + CcspTraceError(("Life Time Setting Failed")); + } + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_RADVD_RESTART, NULL, 0); + } + // update current IPv6 Data + memcpy(&(pIfaceData->IP.Ipv6Data), &(Ipv6DataTemp), sizeof(WANMGR_IPV6_DATA)); + pIfaceData->IP.Ipv6Status = WAN_IFACE_IPV6_STATE_UP; + } + + + //Free buffer + if (pIfaceData->IP.pIpcIpv6Data != NULL ) + { + //free memory + free(pIfaceData->IP.pIpcIpv6Data); + pIfaceData->IP.pIpcIpv6Data = NULL; + } + + return ANSC_STATUS_SUCCESS; +} /* End of ProcessDhcp6cStateChanged() */ + +void* IPV6CPStateChangeHandler (void *arg) +{ + const char *dhcpcInterface = (char *) arg; + if(NULL == dhcpcInterface) + { + return ANSC_STATUS_FAILURE; + } + + pthread_detach(pthread_self()); + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceDataByName_locked(dhcpcInterface); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pIfaceData = &(pWanDmlIfaceData->data); + switch (pIfaceData->PPP.IPV6CPStatus) + { + case WAN_IFACE_IPV6CP_STATUS_UP: + WanManager_StartDhcpv6Client(dhcpcInterface , TRUE); + break; + case WAN_IFACE_IPV6CP_STATUS_DOWN: + WanManager_StopDhcpv6Client(TRUE); + break; + } + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + + free (arg); + + return ANSC_STATUS_SUCCESS; +} diff --git a/source/WanManager/wanmgr_dhcpv6_apis.h b/source/WanManager/wanmgr_dhcpv6_apis.h new file mode 100644 index 00000000..2ae6fb54 --- /dev/null +++ b/source/WanManager/wanmgr_dhcpv6_apis.h @@ -0,0 +1,341 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2019 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +#ifndef _WANMGR_DHCPV6_APIS_H_ +#define _WANMGR_DHCPV6_APIS_H_ +#include +#include +#include +#include +#include + +#include "ansc_platform.h" +#include "ipc_msg.h" +#include "wanmgr_dhcpv4_apis.h" + + +/********************************************************************** + STRUCTURE AND CONSTANT DEFINITIONS +**********************************************************************/ + +#define CCSP_COMMON_FIFO "/tmp/ccsp_common_fifo" + +#define DML_DHCP_MAX_ENTRIES 4 +#define DML_DHCP_MAX_RESERVED_ADDRESSES 8 +#define DML_DHCP_MAX_OPT_ENTRIES 8 + +#define _DEBUG_DHCPV6 +#ifdef _DEBUG_DHCPV6 + #define ULOGF ulogf +#else + #define ULOGF +#endif + +#define COSA_DML_DHCPV6_SERVER_IFNAME CFG_TR181_DHCPv6_SERVER_IfName + +#define COSA_DML_DHCPV6C_PREF_SYSEVENT_NAME "tr_"DML_DHCP_CLIENT_IFNAME"_dhcpv6_client_v6pref" +#define COSA_DML_DHCPV6C_PREF_IAID_SYSEVENT_NAME "tr_"DML_DHCP_CLIENT_IFNAME"_dhcpv6_client_pref_iaid" +#define COSA_DML_DHCPV6C_PREF_T1_SYSEVENT_NAME "tr_"DML_DHCP_CLIENT_IFNAME"_dhcpv6_client_pref_t1" +#define COSA_DML_DHCPV6C_PREF_T2_SYSEVENT_NAME "tr_"DML_DHCP_CLIENT_IFNAME"_dhcpv6_client_pref_t2" +#define COSA_DML_DHCPV6C_PREF_PRETM_SYSEVENT_NAME "tr_"DML_DHCP_CLIENT_IFNAME"_dhcpv6_client_pref_pretm" +#define COSA_DML_DHCPV6C_PREF_VLDTM_SYSEVENT_NAME "tr_"DML_DHCP_CLIENT_IFNAME"_dhcpv6_client_pref_vldtm" + +#define COSA_DML_DHCPV6C_ADDR_SYSEVENT_NAME "tr_"DML_DHCP_CLIENT_IFNAME"_dhcpv6_client_v6addr" +#define COSA_DML_DHCPV6C_ADDR_IAID_SYSEVENT_NAME "tr_"DML_DHCP_CLIENT_IFNAME"_dhcpv6_client_addr_iaid" +#define COSA_DML_DHCPV6C_ADDR_T1_SYSEVENT_NAME "tr_"DML_DHCP_CLIENT_IFNAME"_dhcpv6_client_addr_t1" +#define COSA_DML_DHCPV6C_ADDR_T2_SYSEVENT_NAME "tr_"DML_DHCP_CLIENT_IFNAME"_dhcpv6_client_addr_t2" +#define COSA_DML_DHCPV6C_ADDR_PRETM_SYSEVENT_NAME "tr_"DML_DHCP_CLIENT_IFNAME"_dhcpv6_client_addr_pretm" +#define COSA_DML_DHCPV6C_ADDR_VLDTM_SYSEVENT_NAME "tr_"DML_DHCP_CLIENT_IFNAME"_dhcpv6_client_addr_vldtm" + +#if defined (CISCO_CONFIG_DHCPV6_PREFIX_DELEGATION) || defined (INTEL_PUMA7) +#define COSA_DML_DHCPV6S_ADDR_SYSEVENT_NAME "ipv6_"COSA_DML_DHCPV6_SERVER_IFNAME"-addr" +#else +#define COSA_DML_DHCPV6S_ADDR_SYSEVENT_NAME "tr_"COSA_DML_DHCPV6_SERVER_IFNAME"_dhcpv6_server_v6addr" +#endif + +/* + * DHCP Client + */ + +#ifdef _HUB4_PRODUCT_REQ_ +#define SYSEVENT_MAPT_CONFIG_FLAG "mapt_config_flag" +#define SYSEVENT_MAPT_RATIO "mapt_ratio" +#define SYSEVENT_MAP_RULE_IPADDRESS "map_rule_ip_address" +#define SYSEVENT_MAPT_PSID_OFFSET "mapt_psid_offset" +#define SYSEVENT_MAPT_PSID_VALUE "mapt_psid_value" +#define SYSEVENT_MAPT_PSID_LENGTH "mapt_psid_length" +#define SYSEVENT_MAP_RULE_IPV6_ADDRESS "map_rule_ipv6_address" +#define SYSEVENT_MAP_EA_LEN "map_ea_length" +#define SYSEVENT_MAP_TRANSPORT_MODE "map_transport_mode" +#define SYSEVENT_MAP_IS_FMR "map_is_fmr" +#define SYSEVENT_MAP_BR_IPV6_PREFIX "map_br_ipv6_prefix" +#define SYSEVENT_MAPT_IPADDRESS "mapt_ip_address" +#endif + +typedef struct +_DML_DHCPCV6_SVR +{ + UCHAR SourceAddress[40]; + UCHAR DUID[131]; /* IP interface name */ + UCHAR InformationRefreshTime[32]; +} +DML_DHCPCV6_SVR, *PDML_DHCPCV6_SVR; + +typedef struct +_DML_DHCPCV6_CFG +{ + ULONG InstanceNumber; + UCHAR Alias[DML_ALIAS_NAME_LENGTH]; + LONG SuggestedT1; + LONG SuggestedT2; + UCHAR Interface[DML_ALIAS_NAME_LENGTH]; /* IP interface name */ + UCHAR RequestedOptions[512]; + BOOLEAN bEnabled; + BOOLEAN RequestAddresses; + BOOLEAN RequestPrefixes; + BOOLEAN RapidCommit; + BOOLEAN Renew; +} +DML_DHCPCV6_CFG, *PDML_DHCPCV6_CFG; + +typedef struct +_DML_DHCPCV6_INFO +{ + DML_DHCP_STATUS Status; + UCHAR SupportedOptions[512]; + UCHAR DUID[131]; +} +DML_DHCPCV6_INFO, *PDML_DHCPCV6_INFO; + + +typedef struct +_DML_DHCPCV6_FULL +{ + DML_DHCPCV6_CFG Cfg; + DML_DHCPCV6_INFO Info; +} +DML_DHCPCV6_FULL, *PDML_DHCPCV6_FULL; + +typedef struct +_DML_DHCPCV6_SENT +{ + ULONG InstanceNumber; + UCHAR Alias[DML_ALIAS_NAME_LENGTH]; + + BOOLEAN bEnabled; + ULONG Tag; + UCHAR Value[255]; +} +DML_DHCPCV6_SENT, *PDML_DHCPCV6_SENT; + +struct +_DML_DHCPCV6_RECV +{ + SINGLE_LINK_ENTRY Link; + ULONG Tag; + UCHAR Server[255]; + UCHAR Value[1024]; +}; +typedef struct _DML_DHCPCV6_RECV DML_DHCPCV6_RECV, *PDML_DHCPCV6_RECV; + +#define ACCESS_DHCPV6_RECV_LINK_OBJECT(p) \ + ACCESS_CONTAINER(p, DML_DHCPCV6_RECV, Link) + + +BOOL tagPermitted(int tag); +int _datetime_to_secs(char * p_dt); + +/********************************************************************** + FUNCTION PROTOTYPES +**********************************************************************/ + +ANSC_STATUS +WanMgr_DmlDhcpv6Init + ( + ANSC_HANDLE hDml, + PANSC_HANDLE phContext + ); + + +ULONG +WanMgr_DmlDhcpv6cGetNumberOfEntries + ( + ANSC_HANDLE hContext + ); + +ANSC_STATUS +WanMgr_DmlDhcpv6cGetEntry + ( + ANSC_HANDLE hContext, + ULONG ulIndex, + PDML_DHCPCV6_FULL pEntry + ); + +ANSC_STATUS +WanMgr_DmlDhcpv6cSetValues + ( + ANSC_HANDLE hContext, + ULONG ulIndex, + ULONG ulInstanceNumber, + char* pAlias + ); + +ANSC_STATUS +WanMgr_DmlDhcpv6cAddEntry + ( + ANSC_HANDLE hContext, + PDML_DHCPCV6_FULL pEntry + ); + +ANSC_STATUS +WanMgr_DmlDhcpv6cDelEntry + ( + ANSC_HANDLE hContext, + ULONG ulInstanceNumber + ); + +ANSC_STATUS +WanMgr_DmlDhcpv6cSetCfg + ( + ANSC_HANDLE hContext, + PDML_DHCPCV6_CFG pCfg + ); + +ANSC_STATUS +WanMgr_DmlDhcpv6cGetCfg + ( + ANSC_HANDLE hContext, + PDML_DHCPCV6_CFG pCfg + ); + +ANSC_STATUS +WanMgr_DmlDhcpv6cGetInfo + ( + ANSC_HANDLE hContext, + ULONG ulInstanceNumber, + PDML_DHCPCV6_INFO pInfo + ); + +ANSC_STATUS +WanMgr_DmlDhcpv6cGetServerCfg + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber, + PDML_DHCPCV6_SVR *ppCfg, + PULONG pSize + ); + +ANSC_STATUS +WanMgr_DmlDhcpv6cRenew + ( + ANSC_HANDLE hContext, + ULONG ulInstanceNumber + ); + +ULONG +WanMgr_DmlDhcpv6cGetNumberOfSentOption + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber + ); + +ANSC_STATUS +WanMgr_DmlDhcpv6cGetSentOption + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber, + ULONG ulIndex, + PDML_DHCPCV6_SENT pEntry + ); + +ANSC_STATUS +WanMgr_DmlDhcpv6cGetSentOptionbyInsNum + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber, + PDML_DHCPCV6_SENT pEntry + ); + +ANSC_STATUS +WanMgr_DmlDhcpv6cSetSentOptionValues + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber, + ULONG ulIndex, + ULONG ulInstanceNumber, + char* pAlias + ); + +ANSC_STATUS +WanMgr_DmlDhcpv6cAddSentOption + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber, + PDML_DHCPCV6_SENT pEntry + ); + +ANSC_STATUS +WanMgr_DmlDhcpv6cDelSentOption + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber, + ULONG ulInstanceNumber + ); + +ANSC_STATUS +WanMgr_DmlDhcpv6cSetSentOption + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber, + PDML_DHCPCV6_SENT pEntry + ); + +ANSC_STATUS +WanMgr_DmlDhcpv6cGetReceivedOptionCfg + ( + ANSC_HANDLE hContext, + ULONG ulClientInstanceNumber, + PDML_DHCPCV6_RECV *pEntry, + PULONG pSize + ); +/* TBC -- the functions below should be reviewed, on necessity and name convention */ +void +WanMgr_DmlDhcpv6Remove + ( + ANSC_HANDLE hContext + ); + +int +WanMgr_DmlStartDHCP6Client + ( + void + ); + + + +/** + * @brief API to process DHCP state change event message. + * @param msg - Pointer to msg_payload_t structure contains Dhcpv6 configuration as part of ipc message + * @return ANSC_STATUS_SUCCESS upon success else error code returned. + */ +ANSC_STATUS wanmgr_handle_dchpv6_event_data(DML_WAN_IFACE* pIfaceData); +void* IPV6CPStateChangeHandler (void *arg); + + +#endif //_WANMGR_DHCPV6_APIS_H_ diff --git a/source/WanManager/wanmgr_dhcpv6_internal.c b/source/WanManager/wanmgr_dhcpv6_internal.c new file mode 100644 index 00000000..aaca8708 --- /dev/null +++ b/source/WanManager/wanmgr_dhcpv6_internal.c @@ -0,0 +1,1485 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2015 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +/********************************************************************** + Copyright [2014] [Cisco Systems, Inc.] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +**********************************************************************/ + +/************************************************************************** + + module: wan_dhcpv6_internal.c + + For COSA Data Model Library Development + + ------------------------------------------------------------------- + + description: + + This file implementes back-end apis for the COSA Data Model Library + + * WanMgr_Dhcpv6Create + * WanMgr_Dhcpv6Initialize + * WanMgr_Dhcpv6Remove + * WanMgr_Dhcpv6RegGetDhcpv6Info + * WanMgr_Dhcpv6RegSetDhcpv6Info + * WanMgr_Dhcpv6ClientHasDelayAddedChild + +**************************************************************************/ +#include "wanmgr_apis.h" +#include "wanmgr_dhcpv6_apis.h" +#include "wanmgr_dhcpv6_internal.h" +#include "wanmgr_plugin_main_apis.h" +#include "poam_irepfo_interface.h" +#include "sys_definitions.h" + +extern void * g_pDslhDmlAgent; + + +/********************************************************************** + + caller: owner of the object + + prototype: + + ANSC_HANDLE + WanMgr_Dhcpv6Create + ( + ); + + description: + + This function constructs cosa nat object and return handle. + + argument: + + return: newly created nat object. + +**********************************************************************/ + +ANSC_HANDLE +WanMgr_Dhcpv6Create + ( + VOID + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PWAN_DHCPV6_DATA pMyObject = (PWAN_DHCPV6_DATA) NULL; + + /* + * We create object by first allocating memory for holding the variables and member functions. + */ + pMyObject = (PWAN_DHCPV6_DATA)AnscAllocateMemory(sizeof(WAN_DHCPV6_DATA)); + + if ( !pMyObject ) + { + return (ANSC_HANDLE)NULL; + } + + /* + * Initialize the common variables and functions for a container object. + */ + pMyObject->Oid = WAN_DHCPV6_DATA_OID; + pMyObject->Create = WanMgr_Dhcpv6Create; + pMyObject->Remove = WanMgr_Dhcpv6Remove; + pMyObject->Initialize = WanMgr_Dhcpv6Initialize; + + pMyObject->Initialize ((ANSC_HANDLE)pMyObject); + + return (ANSC_HANDLE)pMyObject; +} + +/********************************************************************** + + caller: self + + prototype: + + ANSC_STATUS + WanMgr_Dhcpv6Initialize + ( + ANSC_HANDLE hThisObject + ); + + description: + + This function initiate cosa nat object and return handle. + + argument: ANSC_HANDLE hThisObject + This handle is actually the pointer of this object + itself. + + return: operation status. + +**********************************************************************/ + +ANSC_STATUS +WanMgr_Dhcpv6Initialize + ( + ANSC_HANDLE hThisObject + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PPOAM_IREP_FOLDER_OBJECT pPoamIrepFoCOSA = NULL; + PPOAM_IREP_FOLDER_OBJECT pPoamIrepFoDhcpv6 = NULL; + PWAN_DHCPV6_DATA pMyObject = (PWAN_DHCPV6_DATA) hThisObject; + + /* We need call the initiation function of backend firstly . + When backend return failure, we don't return because if return, all middle layer function will be not complete*/ + if (pMyObject == NULL) + { + AnscTraceError(("%s:%d:: Pointer is null!!\n", __FUNCTION__, __LINE__)); + return ANSC_STATUS_FAILURE; + } + + WanMgr_DmlDhcpv6Init( NULL, NULL ); + + /* Initiation all functions */ + AnscSListInitializeHeader( &pMyObject->ClientList ); + pMyObject->maxInstanceOfClient = 0; + AnscZeroMemory(pMyObject->AliasOfClient, sizeof(pMyObject->AliasOfClient)); + + /*We need to get Instance Info from cosa configuration*/ + pPoamIrepFoCOSA = (PPOAM_IREP_FOLDER_OBJECT)g_GetRegistryRootFolder(g_pDslhDmlAgent); + if ( !pPoamIrepFoCOSA ) + { + returnStatus = ANSC_STATUS_FAILURE; + return returnStatus; + } + + pPoamIrepFoDhcpv6 = + (PPOAM_IREP_FOLDER_OBJECT)pPoamIrepFoCOSA->GetFolder + ( + (ANSC_HANDLE)pPoamIrepFoCOSA, + DHCPV6_IREP_FOLDER_NAME + ); + + if ( !pPoamIrepFoDhcpv6 ) + { + pPoamIrepFoCOSA->EnableFileSync((ANSC_HANDLE)pPoamIrepFoCOSA, FALSE); + pPoamIrepFoDhcpv6 = + pPoamIrepFoCOSA->AddFolder + ( + (ANSC_HANDLE)pPoamIrepFoCOSA, + DHCPV6_IREP_FOLDER_NAME, + 0 + ); + pPoamIrepFoCOSA->EnableFileSync((ANSC_HANDLE)pPoamIrepFoCOSA, TRUE); + } + + if ( !pPoamIrepFoDhcpv6 ) + { + returnStatus = ANSC_STATUS_FAILURE; + return returnStatus; + } + else + { + pMyObject->hIrepFolderDhcpv6 = (ANSC_HANDLE)pPoamIrepFoDhcpv6; + } + + /* We need get NextInstanceNumber from backend. By the way, the whole tree + was created. Moreover, we also need get delay-added entry and put them + into our tree. */ + WanMgr_Dhcpv6RegGetDhcpv6Info((ANSC_HANDLE)pMyObject); + + /* Firstly we create the whole system from backend */ + WanMgr_Dhcpv6BackendGetDhcpv6Info((ANSC_HANDLE)pMyObject); + + return returnStatus; +} + + + +/********************************************************************** + + caller: self + + prototype: + + ANSC_STATUS + WanMgr_Dhcpv6Remove + ( + ANSC_HANDLE hThisObject + ); + + description: + + This function initiate cosa nat object and return handle. + + argument: ANSC_HANDLE hThisObject + This handle is actually the pointer of this object + itself. + + return: operation status. + +**********************************************************************/ + +ANSC_STATUS +WanMgr_Dhcpv6Remove + ( + ANSC_HANDLE hThisObject + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PDHCPCV6_CONTEXT_LINK_OBJECT pCxtDhcpcLink = NULL; + PCONTEXT_LINK_OBJECT pCxtLink = NULL; + PSINGLE_LINK_ENTRY pSListEntry = NULL; + PSINGLE_LINK_ENTRY pSListEntry2 = NULL; + BOOL bFound = FALSE; + ULONG Index = 0; + PWAN_DHCPV6_DATA pMyObject = (PWAN_DHCPV6_DATA)hThisObject; + + if (pMyObject != NULL) + { + AnscTraceError(("%s:%d:: Pointer is null!!\n", __FUNCTION__, __LINE__)); + return ANSC_STATUS_FAILURE; + } + + PPOAM_IREP_FOLDER_OBJECT pPoamIrepFoDhcpv6 = (PPOAM_IREP_FOLDER_OBJECT)pMyObject->hIrepFolderDhcpv6; + + pSListEntry = AnscSListPopEntry(&pMyObject->ClientList); + while( pSListEntry != NULL) + { + pCxtDhcpcLink = ACCESS_DHCPCV6_CONTEXT_LINK_OBJECT(pSListEntry); + pSListEntry = AnscSListGetNextEntry(pSListEntry); + + pSListEntry2 = AnscSListPopEntry(&pCxtDhcpcLink->SentOptionList); + while( pSListEntry2 != NULL) + { + pCxtLink = ACCESS_CONTEXT_LINK_OBJECT(pSListEntry2); + pSListEntry2 = AnscSListGetNextEntry(pSListEntry2); + AnscFreeMemory(pCxtLink->hContext); + AnscFreeMemory(pCxtLink); + } + + AnscFreeMemory( pCxtDhcpcLink->pServerEntry ); + AnscFreeMemory( pCxtDhcpcLink->pRecvEntry ); + AnscFreeMemory(pCxtDhcpcLink->hContext); + AnscFreeMemory(pCxtDhcpcLink); + } + + if ( pPoamIrepFoDhcpv6 ) + { + pPoamIrepFoDhcpv6->Remove( (ANSC_HANDLE)pPoamIrepFoDhcpv6); + } + + WanMgr_DmlDhcpv6Remove((ANSC_HANDLE)pMyObject); + return returnStatus; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ANSC_STATUS + WanMgr_Dhcpv6RegGetDhcpv6Info + ( + ANSC_HANDLE hThisObject + ); + + description: + + This function is called to retrieve the NextInstanceNumber for every table, Create + the link tree. For delay_added entry, we also need create them. + + argument: ANSC_HANDLE hThisObject + This handle is actually the pointer of DHCPv6 + itself. + + return: status of operation. + +**********************************************************************/ + +ANSC_STATUS +WanMgr_Dhcpv6BackendGetDhcpv6Info + ( + ANSC_HANDLE hThisObject + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PWAN_DHCPV6_DATA pDhcpv6 = (PWAN_DHCPV6_DATA)hThisObject; + + PDML_DHCPCV6_FULL pDhcpc = NULL; + PDML_DHCPCV6_SVR pDhcpcServer = NULL; + PDML_DHCPCV6_RECV pDhcpcRecv = NULL; + PDML_DHCPCV6_SENT pSentOption = NULL; + + ULONG clientCount = 0; + ULONG count = 0; + ULONG count1 = 0; + ULONG ulIndex = 0; + ULONG ulIndex2 = 0; + + PDHCPCV6_CONTEXT_LINK_OBJECT pClientCxtLink = NULL; + PDHCPCV6_CONTEXT_LINK_OBJECT pClientCxtLink2 = NULL; + PCONTEXT_LINK_OBJECT pCxtLink = NULL; + PCONTEXT_LINK_OBJECT pCxtLink2 = NULL; + + BOOL bNeedSave = FALSE; + + /* Get DHCPv6.Client.{i} */ + clientCount = WanMgr_DmlDhcpv6cGetNumberOfEntries(NULL); + for ( ulIndex = 0; ulIndex < clientCount; ulIndex++ ) + { + pDhcpc = (PDML_DHCPCV6_FULL)AnscAllocateMemory( sizeof(DML_DHCPCV6_FULL) ); + if ( !pDhcpc ) + { + break; + } + + DHCPV6_CLIENT_SET_DEFAULTVALUE(pDhcpc); + returnStatus = WanMgr_DmlDhcpv6cGetEntry(NULL, ulIndex, pDhcpc); + if ( returnStatus != ANSC_STATUS_SUCCESS ) + { + AnscFreeMemory(pDhcpc); + break; + } + + pClientCxtLink = (PDHCPCV6_CONTEXT_LINK_OBJECT)AnscAllocateMemory( sizeof(DHCPCV6_CONTEXT_LINK_OBJECT) ); + if ( !pClientCxtLink ) + { + AnscFreeMemory(pDhcpc); + break; + } + + DHCPV6_CLIENT_INITIATION_CONTEXT(pClientCxtLink) + pClientCxtLink->hContext = (ANSC_HANDLE)pDhcpc; + pClientCxtLink->bNew = FALSE; + pClientCxtLink->hParentTable = (ANSC_HANDLE)pDhcpv6; + + if ( !pDhcpc->Cfg.InstanceNumber ) + { + if ( !++pDhcpv6->maxInstanceOfClient ) + { + pDhcpv6->maxInstanceOfClient = 1; + } + bNeedSave = TRUE; + + pDhcpc->Cfg.InstanceNumber = pDhcpv6->maxInstanceOfClient; + pClientCxtLink->InstanceNumber = pDhcpc->Cfg.InstanceNumber; + + _ansc_sprintf((char *)pDhcpc->Cfg.Alias, "DHCPv6%lu", pDhcpc->Cfg.InstanceNumber); + + returnStatus = WanMgr_DmlDhcpv6cSetValues + ( + NULL, + ulIndex, + pDhcpc->Cfg.InstanceNumber, + (char *)pDhcpc->Cfg.Alias + ); + + if ( returnStatus != ANSC_STATUS_SUCCESS ) + { + AnscFreeMemory(pDhcpc); + AnscFreeMemory(pClientCxtLink); + break; + } + + /* Put into our list */ + SListPushEntryByInsNum(&pDhcpv6->ClientList, (PCONTEXT_LINK_OBJECT)pClientCxtLink); + } + else + { + pClientCxtLink->InstanceNumber = pDhcpc->Cfg.InstanceNumber; + + /* This case never happen. Add it just for simulation code run well */ + if ( pDhcpv6->maxInstanceOfClient < pClientCxtLink->InstanceNumber ) + { + pDhcpv6->maxInstanceOfClient = pClientCxtLink->InstanceNumber; + bNeedSave = TRUE; + } + + /* if this entry is in link tree already because it's the parent of delay_added table */ + pClientCxtLink2 = (PDHCPCV6_CONTEXT_LINK_OBJECT)SListGetEntryByInsNum(&pDhcpv6->ClientList, pClientCxtLink->InstanceNumber); + if ( !pClientCxtLink2 ) + { + SListPushEntryByInsNum(&pDhcpv6->ClientList, (PCONTEXT_LINK_OBJECT)pClientCxtLink); + } + else + { + /* When this case happens, somethings happens to be error. We harmonize it here.*/ + AnscFreeMemory( pClientCxtLink2->hContext ); + pClientCxtLink2->hContext = (ANSC_HANDLE)pDhcpc; + if ( pClientCxtLink2->bNew ) + { + pClientCxtLink2->bNew = FALSE; + bNeedSave = TRUE; + } + + AnscFreeMemory(pClientCxtLink); + pClientCxtLink = pClientCxtLink2; + pClientCxtLink2 = NULL; + } + } + + /* We begin treat DHCPv6.Client.{i}.Server.{i} + This is one dynamic table. We get all once */ + returnStatus = WanMgr_DmlDhcpv6cGetServerCfg + ( + NULL, + pDhcpc->Cfg.InstanceNumber, + &pDhcpcServer, + &count + ); + if ( returnStatus == ANSC_STATUS_SUCCESS ) + { + pClientCxtLink->pServerEntry = pDhcpcServer; + pClientCxtLink->NumberOfServer = count; + } + else + { + CcspTraceWarning(("WanMgr_Dhcpv6BackendGetDhcpv6Info -- WanMgr_DmlDhcpv6cGetServerCfg() return error:%d.\n", returnStatus)); + } + + /* We begin treat DHCPv6.Client.{i}.SentOption.{i} */ + count = WanMgr_DmlDhcpv6cGetNumberOfSentOption + ( + NULL, + pDhcpc->Cfg.InstanceNumber + ); + + for ( ulIndex2 = 0; ulIndex2 < count; ulIndex2++ ) + { + pSentOption = (PDML_DHCPCV6_SENT)AnscAllocateMemory( sizeof(DML_DHCPCV6_SENT) ); + if ( !pSentOption ) + { + break; + } + + DHCPV6_SENTOPTION_SET_DEFAULTVALUE(pSentOption); + returnStatus = WanMgr_DmlDhcpv6cGetSentOption + ( + NULL, + pDhcpc->Cfg.InstanceNumber, + ulIndex2, + pSentOption + ); + if ( returnStatus != ANSC_STATUS_SUCCESS ) + { + AnscFreeMemory(pSentOption); + break; + } + + pCxtLink = (PCONTEXT_LINK_OBJECT)AnscAllocateMemory( sizeof(CONTEXT_LINK_OBJECT) ); + if ( !pCxtLink ) + { + AnscFreeMemory(pSentOption); + break; + } + + CONTEXT_LINK_INITIATION_CONTENT(pCxtLink); + pCxtLink->hContext = (ANSC_HANDLE)pSentOption; + pCxtLink->hParentTable = (ANSC_HANDLE)pClientCxtLink; + pCxtLink->bNew = FALSE; + + if ( !pSentOption->InstanceNumber ) + { + if ( !++pClientCxtLink->maxInstanceOfSent ) + { + pClientCxtLink->maxInstanceOfSent = 1; + bNeedSave = TRUE; + } + bNeedSave = TRUE; + pSentOption->InstanceNumber = pClientCxtLink->maxInstanceOfSent; + + _ansc_sprintf( (char *)pSentOption->Alias, "SentOption%lu", pSentOption->InstanceNumber ); + + returnStatus = WanMgr_DmlDhcpv6cSetSentOptionValues + ( + NULL, + pDhcpc->Cfg.InstanceNumber, + ulIndex, + pSentOption->InstanceNumber, + (char *)pSentOption->Alias + ); + + if ( returnStatus != ANSC_STATUS_SUCCESS ) + { + AnscFreeMemory(pSentOption); + AnscFreeMemory(pCxtLink); + break; + } + + pCxtLink->InstanceNumber = pSentOption->InstanceNumber; + + /* Put into our list */ + SListPushEntryByInsNum(&pClientCxtLink->SentOptionList, (PCONTEXT_LINK_OBJECT)pCxtLink); + + } + else + { + pCxtLink->InstanceNumber = pSentOption->InstanceNumber; + + /* This case never happen. Add it just for simulation code run well */ + if ( pClientCxtLink->maxInstanceOfSent < pSentOption->InstanceNumber ) + { + pClientCxtLink->maxInstanceOfSent = pSentOption->InstanceNumber; + } + + /* if this entry is in link tree already because it's delay_added table */ + pCxtLink2 = (PCONTEXT_LINK_OBJECT)SListGetEntryByInsNum(&pClientCxtLink->SentOptionList, pSentOption->InstanceNumber); + if ( !pCxtLink2 ) + { + SListPushEntryByInsNum(&pClientCxtLink->SentOptionList, (PCONTEXT_LINK_OBJECT)pCxtLink); + } + else + { + AnscFreeMemory( pCxtLink2->hContext ); + pCxtLink2->hContext = (ANSC_HANDLE)pSentOption; + if ( pCxtLink2->bNew ) + { + pCxtLink2->bNew = FALSE; + bNeedSave = TRUE; + } + + AnscFreeMemory(pCxtLink); + pCxtLink = pCxtLink2; + pCxtLink2 = NULL; + } + + } + } + // WanMgr_DmlStartDHCP6Client(); + /* We begin treat DHCPv6.Client.{i}.ReceivedOption.{i} + This is one dynamic table. We get all once */ + returnStatus = WanMgr_DmlDhcpv6cGetReceivedOptionCfg + ( + NULL, + pDhcpc->Cfg.InstanceNumber, + &pDhcpcRecv, + &count + ); + if ( returnStatus == ANSC_STATUS_SUCCESS ) + { + pClientCxtLink->pRecvEntry = pDhcpcRecv; + pClientCxtLink->NumberOfRecv = count; + } + else + { + CcspTraceWarning(("WanMgr_Dhcpv6BackendGetDhcpv6Info -- WanMgr_DmlDhcpv6cGetReceivedOptionCfg() return error:%d.\n", returnStatus)); + } + + } + + return returnStatus; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ANSC_STATUS + WanMgr_Dhcpv6RegGetDhcpv6Info + ( + ANSC_HANDLE hThisObject + ); + + description: + + This function is called to retrieve backend inform and put them into our trees. + + argument: ANSC_HANDLE hThisObject + This handle is actually the pointer of DHCPv6 + itself. + + return: status of operation. + +**********************************************************************/ + +ANSC_STATUS +WanMgr_Dhcpv6RegGetDhcpv6Info + ( + ANSC_HANDLE hThisObject + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PWAN_DHCPV6_DATA pMyObject = (PWAN_DHCPV6_DATA )hThisObject; + + PPOAM_IREP_FOLDER_OBJECT pPoamIrepFoDhcpv6 = (PPOAM_IREP_FOLDER_OBJECT )pMyObject->hIrepFolderDhcpv6; + PPOAM_IREP_FOLDER_OBJECT pPoamIrepFoClient = (PPOAM_IREP_FOLDER_OBJECT )NULL; + PPOAM_IREP_FOLDER_OBJECT pPoamIrepFoSntOpt = (PPOAM_IREP_FOLDER_OBJECT )NULL; + + PPOAM_IREP_FOLDER_OBJECT pPoamIrepFoEnumClient = (PPOAM_IREP_FOLDER_OBJECT )NULL; + PPOAM_IREP_FOLDER_OBJECT pPoamIrepFoEnumSntOpt = (PPOAM_IREP_FOLDER_OBJECT )NULL; + + PDHCPCV6_CONTEXT_LINK_OBJECT pDhcpcContext = NULL; + PCONTEXT_LINK_OBJECT pDhcpv6SentOptionContext = NULL; + + PSLAP_VARIABLE pSlapVariable = NULL; + ULONG ulEntryCount = 0; + ULONG ulIndex = 0; + ULONG ulEntryCount2 = 0; + ULONG ulIndex2 = 0; + ULONG uInstanceNumber = 0; + BOOL bNew = FALSE; + char* pAliasClient = NULL; + char* pAliasSentOption = NULL; + char* pFolderName = NULL; + + PDML_DHCPCV6_FULL pDhcpv6Client = NULL; + PDML_DHCPCV6_SENT pDhcpv6SntOpt = NULL; + + if ( !pPoamIrepFoDhcpv6 ) + { + return ANSC_STATUS_FAILURE; + } + + /* This is saved structure for DHCPv6 + ***************************************** + + + xxx + <1> + xxx + false + + xxx + <1> + xxx + true + + + + + + xxx + <1> + xxx + true + + + + + **************************************************** + */ + + /* Get Folder Client */ + pPoamIrepFoClient = + (PPOAM_IREP_FOLDER_OBJECT)pPoamIrepFoDhcpv6->GetFolder + ( + (ANSC_HANDLE)pPoamIrepFoDhcpv6, + DHCPV6_IREP_FOLDER_NAME_CLIENT + ); + + if ( !pPoamIrepFoClient ) + { + returnStatus = ANSC_STATUS_FAILURE; + goto EXIT1; + } + + /* Get Client.NextInstanceNumber */ + if ( TRUE ) + { + pSlapVariable = + (PSLAP_VARIABLE)pPoamIrepFoClient->GetRecord + ( + (ANSC_HANDLE)pPoamIrepFoClient, + COSA_DML_RR_NAME_Dhcpv6NextInsNunmber, + NULL + ); + + if ( pSlapVariable ) + { + pMyObject->maxInstanceOfClient = pSlapVariable->Variant.varUint32; + + SlapFreeVariable(pSlapVariable); + } + } + + /* enumerate client.{i} */ + ulEntryCount = pPoamIrepFoClient->GetFolderCount((ANSC_HANDLE)pPoamIrepFoClient); + for ( ulIndex = 0; ulIndex < ulEntryCount; ulIndex++ ) + { + /* Get i in client.{i} */ + pFolderName = + pPoamIrepFoClient->EnumFolder + ( + (ANSC_HANDLE)pPoamIrepFoClient, + ulIndex + ); + + if ( !pFolderName ) + { + continue; + } + + uInstanceNumber = _ansc_atol(pFolderName); + + if ( uInstanceNumber == 0 ) + { + AnscFreeMemory(pFolderName); + continue; + } + + /*get folder client.{i} */ + pPoamIrepFoEnumClient = pPoamIrepFoClient->GetFolder((ANSC_HANDLE)pPoamIrepFoClient, pFolderName); + + AnscFreeMemory(pFolderName); + + if ( !pPoamIrepFoEnumClient ) + { + continue; + } + + /* Get client.{i}.Alias value*/ + if ( TRUE ) + { + pSlapVariable = + (PSLAP_VARIABLE)pPoamIrepFoEnumClient->GetRecord + ( + (ANSC_HANDLE)pPoamIrepFoEnumClient, + COSA_DML_RR_NAME_Dhcpv6Alias, + NULL + ); + + if ( pSlapVariable ) + { + pAliasClient = AnscCloneString(pSlapVariable->Variant.varString); + + SlapFreeVariable(pSlapVariable); + } + } + + /* Get client.{i}.bNew value*/ + if ( TRUE ) + { + pSlapVariable = + (PSLAP_VARIABLE)pPoamIrepFoEnumClient->GetRecord + ( + (ANSC_HANDLE)pPoamIrepFoEnumClient, + COSA_DML_RR_NAME_Dhcpv6bNew, + NULL + ); + + if ( pSlapVariable ) + { + bNew = pSlapVariable->Variant.varBool; + + SlapFreeVariable(pSlapVariable); + } + else + { + bNew = TRUE; + } + } + + /* Create one entry and keep this delay_added entry */ + /* Firstly create dhcpc content struct */ + pDhcpv6Client = (PDML_DHCPCV6_FULL)AnscAllocateMemory(sizeof(DML_DHCPCV6_FULL)); + if ( !pDhcpv6Client ) + { + returnStatus = ANSC_STATUS_FAILURE; + goto EXIT2; + } + + /* set some default value firstly */ + DHCPV6_CLIENT_SET_DEFAULTVALUE(pDhcpv6Client); + + /* save alias and instanceNumber */ + pDhcpv6Client->Cfg.InstanceNumber = uInstanceNumber; + AnscCopyString( (char *)pDhcpv6Client->Cfg.Alias, pAliasClient ); + if (pAliasClient) + { + AnscFreeMemory(pAliasClient); + pAliasClient = NULL; + } + + /* Create one link point */ + pDhcpcContext = (PDHCPCV6_CONTEXT_LINK_OBJECT)AnscAllocateMemory(sizeof(DHCPCV6_CONTEXT_LINK_OBJECT)); + if ( !pDhcpcContext ) + { + returnStatus = ANSC_STATUS_FAILURE; + goto EXIT3; + } + + DHCPV6_CLIENT_INITIATION_CONTEXT(pDhcpcContext) + + pDhcpcContext->InstanceNumber = uInstanceNumber; + pDhcpcContext->hContext = (ANSC_HANDLE)pDhcpv6Client; + pDhcpv6Client = NULL; /* reset to NULL */ + pDhcpcContext->bNew = bNew; /* set to true */ + + SListPushEntryByInsNum(&pMyObject->ClientList, (PCONTEXT_LINK_OBJECT)pDhcpcContext); + + /* + Begin treat client.{i}.sentOption. + */ + pPoamIrepFoSntOpt = + (PPOAM_IREP_FOLDER_OBJECT)pPoamIrepFoEnumClient->GetFolder + ( + (ANSC_HANDLE)pPoamIrepFoEnumClient, + DHCPV6_IREP_FOLDER_NAME_SENTOPTION + ); + + if ( !pPoamIrepFoSntOpt ) + { + goto ClientEnd; + } + + /* Get Maximum number */ + if ( TRUE ) + { + pSlapVariable = + (PSLAP_VARIABLE)pPoamIrepFoSntOpt->GetRecord + ( + (ANSC_HANDLE)pPoamIrepFoSntOpt, + COSA_DML_RR_NAME_Dhcpv6NextInsNunmber, + NULL + ); + + if ( pSlapVariable ) + { + pDhcpcContext->maxInstanceOfSent = pSlapVariable->Variant.varUint32; + + SlapFreeVariable(pSlapVariable); + } + } + + /* enumerate client.{i}.sentOption.{i} */ + ulEntryCount2 = pPoamIrepFoSntOpt->GetFolderCount((ANSC_HANDLE)pPoamIrepFoSntOpt); + + for ( ulIndex2 = 0; ulIndex2 < ulEntryCount2; ulIndex2++ ) + { + /* Get i in client.{i}.sentOption.{i} */ + pFolderName = + pPoamIrepFoSntOpt->EnumFolder + ( + (ANSC_HANDLE)pPoamIrepFoSntOpt, + ulIndex2 + ); + + if ( !pFolderName ) + { + continue; + } + + uInstanceNumber = _ansc_atol(pFolderName); + + if ( uInstanceNumber == 0 ) + { + AnscFreeMemory(pFolderName); /* tom*/ + continue; + } + + pPoamIrepFoEnumSntOpt = pPoamIrepFoSntOpt->GetFolder((ANSC_HANDLE)pPoamIrepFoSntOpt, pFolderName); + + AnscFreeMemory(pFolderName); + + if ( !pPoamIrepFoEnumSntOpt ) + { + continue; + } + + /* Get client.{i}.sentOption.{i}.Alias value*/ + if ( TRUE ) + { + pSlapVariable = + (PSLAP_VARIABLE)pPoamIrepFoEnumSntOpt->GetRecord + ( + (ANSC_HANDLE)pPoamIrepFoEnumSntOpt, + COSA_DML_RR_NAME_Dhcpv6Alias, + NULL + ); + + if ( pSlapVariable ) + { + pAliasSentOption = AnscCloneString(pSlapVariable->Variant.varString); + + SlapFreeVariable(pSlapVariable); + } + } + + /* Get client.{i}.sentOption.{i}.bNew value*/ + if ( TRUE ) + { + pSlapVariable = + (PSLAP_VARIABLE)pPoamIrepFoEnumSntOpt->GetRecord + ( + (ANSC_HANDLE)pPoamIrepFoEnumSntOpt, + COSA_DML_RR_NAME_Dhcpv6bNew, + NULL + ); + + if ( pSlapVariable ) + { + bNew = pSlapVariable->Variant.varBool; + + SlapFreeVariable(pSlapVariable); + } + else + { + bNew = TRUE; + } + } + + /* Create one link and ask backend to get content */ + pDhcpv6SntOpt = (PDML_DHCPCV6_SENT)AnscAllocateMemory(sizeof(DML_DHCPCV6_SENT)); + if ( !pDhcpv6SntOpt ) + { + returnStatus = ANSC_STATUS_FAILURE; + AnscFreeMemory(pDhcpv6SntOpt); /*RDKB-6737, CID-32983, free unused resource before exit*/ + pDhcpv6SntOpt = NULL; + goto EXIT3; + } + + /* set some default value firstly */ + DHCPV6_SENTOPTION_SET_DEFAULTVALUE(pDhcpv6SntOpt); + + /* save alias and instanceNumber */ + pDhcpv6SntOpt->InstanceNumber = uInstanceNumber; + AnscCopyString((char *) pDhcpv6SntOpt->Alias, pAliasSentOption ); + if (pAliasSentOption) + { + AnscFreeMemory(pAliasSentOption); + pAliasSentOption = NULL; + } + + pDhcpv6SentOptionContext = (PCONTEXT_LINK_OBJECT)AnscAllocateMemory(sizeof(CONTEXT_LINK_OBJECT)); + if ( !pDhcpv6SentOptionContext ) + { + returnStatus = ANSC_STATUS_FAILURE; + goto EXIT2; + } + + CONTEXT_LINK_INITIATION_CONTENT(pDhcpv6SentOptionContext); + + pDhcpv6SentOptionContext->InstanceNumber = uInstanceNumber; + pDhcpv6SentOptionContext->hContext = (ANSC_HANDLE)pDhcpv6SntOpt; + pDhcpv6SntOpt = NULL; + pDhcpv6SentOptionContext->hParentTable = pDhcpcContext; + pDhcpv6SentOptionContext->bNew = bNew; + + SListPushEntryByInsNum(&pDhcpcContext->SentOptionList, (PCONTEXT_LINK_OBJECT)pDhcpv6SentOptionContext); + + /* release some memory */ + pPoamIrepFoEnumSntOpt->Remove((ANSC_HANDLE)pPoamIrepFoEnumSntOpt); + pPoamIrepFoEnumSntOpt = NULL; + } + + pPoamIrepFoSntOpt->Remove((ANSC_HANDLE)pPoamIrepFoSntOpt); + pPoamIrepFoSntOpt = NULL; + +ClientEnd: + /* release some memory */ + pPoamIrepFoEnumClient->Remove((ANSC_HANDLE)pPoamIrepFoEnumClient); + pPoamIrepFoEnumClient = NULL; + + } + + pPoamIrepFoClient->Remove((ANSC_HANDLE)pPoamIrepFoClient); + pPoamIrepFoClient = NULL; + +EXIT3: + if(pDhcpv6Client) + AnscFreeMemory(pDhcpv6Client); + +EXIT2: + + if(pAliasSentOption) + AnscFreeMemory(pAliasSentOption); + + if(pAliasClient) + AnscFreeMemory(pAliasClient); + + if(pDhcpv6SntOpt ) + AnscFreeMemory(pDhcpv6SntOpt); + +EXIT1: + + if ( pPoamIrepFoClient ) + pPoamIrepFoClient->Remove((ANSC_HANDLE)pPoamIrepFoClient); + + if ( pPoamIrepFoEnumClient ) + pPoamIrepFoEnumClient->Remove((ANSC_HANDLE)pPoamIrepFoEnumClient); + + if ( pPoamIrepFoSntOpt) + pPoamIrepFoSntOpt->Remove((ANSC_HANDLE)pPoamIrepFoSntOpt); + + if ( pPoamIrepFoEnumSntOpt) + pPoamIrepFoEnumSntOpt->Remove((ANSC_HANDLE)pPoamIrepFoEnumSntOpt); + + return returnStatus; +} + +/********************************************************************** + + caller: owner of this object + + prototype: + + ANSC_STATUS + WanMgr_Dhcpv6RegSetDhcpv6Info + ( + ANSC_HANDLE hThisObject + ); + + description: + + This function is called to save current NextInstanceNumber and Delay_added + entry into sysregistry. + + argument: ANSC_HANDLE hThisObject + This handle is actually the pointer of DHCPv6 + itself. + + return: status of operation. + +**********************************************************************/ + +ANSC_STATUS +WanMgr_Dhcpv6RegSetDhcpv6Info + ( + ANSC_HANDLE hThisObject + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PWAN_DHCPV6_DATA pMyObject = (PWAN_DHCPV6_DATA )hThisObject; + + PPOAM_IREP_FOLDER_OBJECT pPoamIrepFoDhcpv6 = (PPOAM_IREP_FOLDER_OBJECT )pMyObject->hIrepFolderDhcpv6; + PPOAM_IREP_FOLDER_OBJECT pPoamIrepFoClient = (PPOAM_IREP_FOLDER_OBJECT )NULL; + PPOAM_IREP_FOLDER_OBJECT pPoamIrepFoSntOpt = (PPOAM_IREP_FOLDER_OBJECT )NULL; + PPOAM_IREP_FOLDER_OBJECT pPoamIrepFoPool = (PPOAM_IREP_FOLDER_OBJECT )NULL; + PPOAM_IREP_FOLDER_OBJECT pPoamIrepFoPoolOption = (PPOAM_IREP_FOLDER_OBJECT )NULL; + + PPOAM_IREP_FOLDER_OBJECT pPoamIrepFoEnumClient = (PPOAM_IREP_FOLDER_OBJECT )NULL; + PPOAM_IREP_FOLDER_OBJECT pPoamIrepFoEnumSntOpt = (PPOAM_IREP_FOLDER_OBJECT )NULL; + PPOAM_IREP_FOLDER_OBJECT pPoamIrepFoEnumPool = (PPOAM_IREP_FOLDER_OBJECT )NULL; + PPOAM_IREP_FOLDER_OBJECT pPoamIrepFoEnumPoolOption = (PPOAM_IREP_FOLDER_OBJECT )NULL; + + PSINGLE_LINK_ENTRY pSLinkEntry = (PSINGLE_LINK_ENTRY )NULL; + PSINGLE_LINK_ENTRY pSLinkEntry2 = (PSINGLE_LINK_ENTRY )NULL; + + PDHCPCV6_CONTEXT_LINK_OBJECT pDhcpcContext = NULL; + PCONTEXT_LINK_OBJECT pSentOptionContext = NULL; + + PSLAP_VARIABLE pSlapVariable = NULL; + ULONG ulEntryCount = 0; + ULONG ulIndex = 0; + ULONG ulEntryCount2 = 0; + ULONG ulIndex2 = 0; + ULONG uInstanceNumber = 0; + char* pAliasClient = NULL; + char* pAliasSentOption = NULL; + char* pAliasPool = NULL; + char* pAliasPoolOption = NULL; + char* pFolderName = NULL; + char FolderName[16] = {0}; + + PDML_DHCPCV6_FULL pDhcpv6Client = NULL; + PDML_DHCPCV6_SENT pDhcpv6SntOpt = NULL; + + if ( !pPoamIrepFoDhcpv6 ) + { + return ANSC_STATUS_FAILURE; + } + else + { + pPoamIrepFoDhcpv6->EnableFileSync((ANSC_HANDLE)pPoamIrepFoDhcpv6, FALSE); + } + + if ( TRUE ) + { + pPoamIrepFoDhcpv6->Clear((ANSC_HANDLE)pPoamIrepFoDhcpv6); + + SlapAllocVariable(pSlapVariable); + + if ( !pSlapVariable ) + { + returnStatus = ANSC_STATUS_RESOURCES; + + goto EXIT1; + } + } + + /* This is saved structure for DHCPv6 + ***************************************** + + + xxx + <1> + xxx + false + + xxx + <1> + xxx + true + + + + + + xxx + <1> + xxx + true + + + + + **************************************************** + */ + + /* Add DHCPv6.client.*/ + pPoamIrepFoClient = + pPoamIrepFoDhcpv6->AddFolder + ( + (ANSC_HANDLE)pPoamIrepFoDhcpv6, + DHCPV6_IREP_FOLDER_NAME_CLIENT, + 0 + ); + + if ( !pPoamIrepFoClient ) + { + goto EXIT1; + } + + /* add client.{i}.NextInstanceNumber */ + if ( TRUE ) + { + pSlapVariable->Syntax = SLAP_VAR_SYNTAX_uint32; + pSlapVariable->Variant.varUint32 = pMyObject->maxInstanceOfClient; + + returnStatus = + pPoamIrepFoClient->AddRecord + ( + (ANSC_HANDLE)pPoamIrepFoClient, + COSA_DML_RR_NAME_Dhcpv6NextInsNunmber, + SYS_REP_RECORD_TYPE_UINT, + SYS_RECORD_CONTENT_DEFAULT, + pSlapVariable, + 0 + ); + + SlapCleanVariable(pSlapVariable); + SlapInitVariable (pSlapVariable); + } + + pSLinkEntry = AnscSListGetFirstEntry(&pMyObject->ClientList); + + while ( pSLinkEntry ) + { + /* create DHCPv6.client.{i} */ + + pDhcpcContext = ACCESS_DHCPCV6_CONTEXT_LINK_OBJECT(pSLinkEntry); + pSLinkEntry = AnscSListGetNextEntry(pSLinkEntry); + + pDhcpv6Client = (PDML_DHCPCV6_FULL)pDhcpcContext->hContext; + + /* When this entry has been added to backend, has not any child and maxInstanceNumber is 0 + We need not save this entry */ + if ( !pDhcpcContext->bNew && + !AnscSListQueryDepth(&pDhcpcContext->SentOptionList ) && + ( pDhcpcContext->maxInstanceOfSent == 0 ) + ) + { + continue; + } + + _ansc_sprintf(FolderName, "%lu", pDhcpcContext->InstanceNumber); + + pPoamIrepFoEnumClient = + pPoamIrepFoClient->AddFolder + ( + (ANSC_HANDLE)pPoamIrepFoClient, + FolderName, + 0 + ); + + if ( !pPoamIrepFoEnumClient ) + { + continue; + } + + /* add DHCPv6.client.{i}.alias */ + if ( TRUE ) + { + pSlapVariable->Syntax = SLAP_VAR_SYNTAX_string; + pSlapVariable->Variant.varString = AnscCloneString((char *)pDhcpv6Client->Cfg.Alias); + + returnStatus = + pPoamIrepFoEnumClient->AddRecord + ( + (ANSC_HANDLE)pPoamIrepFoEnumClient, + COSA_DML_RR_NAME_Dhcpv6Alias, + SYS_REP_RECORD_TYPE_ASTR, + SYS_RECORD_CONTENT_DEFAULT, + pSlapVariable, + 0 + ); + + SlapCleanVariable(pSlapVariable); + SlapInitVariable (pSlapVariable); + } + + /* add DHCPv6.client.{i}.bNew */ + if ( TRUE ) + { + pSlapVariable->Syntax = SLAP_VAR_SYNTAX_bool; + pSlapVariable->Variant.varBool = pDhcpcContext->bNew; + + returnStatus = + pPoamIrepFoEnumClient->AddRecord + ( + (ANSC_HANDLE)pPoamIrepFoEnumClient, + COSA_DML_RR_NAME_Dhcpv6bNew, + SYS_REP_RECORD_TYPE_BOOL, + SYS_RECORD_CONTENT_DEFAULT, + pSlapVariable, + 0 + ); + + SlapCleanVariable(pSlapVariable); + SlapInitVariable (pSlapVariable); + } + + /* + begin add sentOption + */ + if ( !AnscSListQueryDepth(&pDhcpcContext->SentOptionList) ) + { + goto ClientEnd; + } + + /* Add DHCPv6.client.{i}.sentOption */ + pPoamIrepFoSntOpt = + pPoamIrepFoEnumClient->AddFolder + ( + (ANSC_HANDLE)pPoamIrepFoEnumClient, + DHCPV6_IREP_FOLDER_NAME_SENTOPTION, + 0 + ); + + if ( !pPoamIrepFoSntOpt ) + { + goto EXIT1; + } + + /* add client.{i}.sendOption.maxInstanceNumber */ + if ( TRUE ) + { + pSlapVariable->Syntax = SLAP_VAR_SYNTAX_uint32; + pSlapVariable->Variant.varUint32 = pDhcpcContext->maxInstanceOfSent; + + returnStatus = + pPoamIrepFoSntOpt->AddRecord + ( + (ANSC_HANDLE)pPoamIrepFoSntOpt, + COSA_DML_RR_NAME_Dhcpv6NextInsNunmber, + SYS_REP_RECORD_TYPE_UINT, + SYS_RECORD_CONTENT_DEFAULT, + pSlapVariable, + 0 + ); + + SlapCleanVariable(pSlapVariable); + SlapInitVariable (pSlapVariable); + } + + pSLinkEntry2 = AnscSListGetFirstEntry(&pDhcpcContext->SentOptionList); + + while ( pSLinkEntry2 ) + { + /* create DHCPv6.client.{i}.sentOption.{i} */ + + pSentOptionContext = ACCESS_CONTEXT_LINK_OBJECT(pSLinkEntry2); + pSLinkEntry2 = AnscSListGetNextEntry(pSLinkEntry2); + + pDhcpv6SntOpt= (PDML_DHCPCV6_SENT)pSentOptionContext->hContext; + + if ( !pSentOptionContext->bNew ) + { + continue; + } + + _ansc_sprintf(FolderName, "%lu", pSentOptionContext->InstanceNumber); + + pPoamIrepFoEnumSntOpt = + pPoamIrepFoSntOpt->AddFolder + ( + (ANSC_HANDLE)pPoamIrepFoSntOpt, + FolderName, + 0 + ); + + if ( !pPoamIrepFoEnumSntOpt ) + { + continue; + } + + /* create DHCPv6.client.{i}.sendOption.{i}.alias */ + if ( TRUE ) + { + pSlapVariable->Syntax = SLAP_VAR_SYNTAX_string; + pSlapVariable->Variant.varString = AnscCloneString((char *)pDhcpv6SntOpt->Alias); + + returnStatus = + pPoamIrepFoEnumSntOpt->AddRecord + ( + (ANSC_HANDLE)pPoamIrepFoEnumSntOpt, + COSA_DML_RR_NAME_Dhcpv6Alias, + SYS_REP_RECORD_TYPE_ASTR, + SYS_RECORD_CONTENT_DEFAULT, + pSlapVariable, + 0 + ); + + SlapCleanVariable(pSlapVariable); + SlapInitVariable (pSlapVariable); + } + + /* create DHCPv6.client.{i}.sendOption.{i}.bNew */ + if ( TRUE ) + { + pSlapVariable->Syntax = SLAP_VAR_SYNTAX_bool; + pSlapVariable->Variant.varBool = pSentOptionContext->bNew; + + returnStatus = + pPoamIrepFoEnumSntOpt->AddRecord + ( + (ANSC_HANDLE)pPoamIrepFoEnumSntOpt, + COSA_DML_RR_NAME_Dhcpv6bNew, + SYS_REP_RECORD_TYPE_BOOL, + SYS_RECORD_CONTENT_DEFAULT, + pSlapVariable, + 0 + ); + + SlapCleanVariable(pSlapVariable); + SlapInitVariable (pSlapVariable); + } + + pPoamIrepFoEnumSntOpt->Remove((ANSC_HANDLE)pPoamIrepFoEnumSntOpt); + pPoamIrepFoEnumSntOpt = NULL; + } + + pPoamIrepFoSntOpt->Remove((ANSC_HANDLE)pPoamIrepFoSntOpt); + pPoamIrepFoSntOpt = NULL; + +ClientEnd: + + /*release some resource */ + pPoamIrepFoEnumClient->Remove((ANSC_HANDLE)pPoamIrepFoEnumClient); + pPoamIrepFoEnumClient = NULL; + } + + pPoamIrepFoClient->Remove((ANSC_HANDLE)pPoamIrepFoClient); + pPoamIrepFoClient = NULL; + + +EXIT1: + if ( pSlapVariable ) + { + SlapFreeVariable(pSlapVariable); + pSlapVariable = NULL; + } + + if ( pPoamIrepFoClient ) + pPoamIrepFoClient->Remove((ANSC_HANDLE)pPoamIrepFoClient); + + if ( pPoamIrepFoEnumClient ) + pPoamIrepFoEnumClient->Remove((ANSC_HANDLE)pPoamIrepFoEnumClient); + + if ( pPoamIrepFoSntOpt) + pPoamIrepFoSntOpt->Remove((ANSC_HANDLE)pPoamIrepFoSntOpt); + + if ( pPoamIrepFoEnumSntOpt) + pPoamIrepFoEnumSntOpt->Remove((ANSC_HANDLE)pPoamIrepFoEnumSntOpt); + + pPoamIrepFoDhcpv6->EnableFileSync((ANSC_HANDLE)pPoamIrepFoDhcpv6, TRUE); + + return returnStatus; +} + + +/********************************************************************** + + caller: owner of this object + + prototype: + + BOOL + WanMgr_Dhcpv6ClientHasDelayAddedChild + ( + PDHCPC_CONTEXT_LINK_OBJECT hContext + ); + + description: + + This function is called to check whether this is child is pending added. If yes, + return TRUE. Or else return FALSE. + + argument: PDHCPC_CONTEXT_LINK_OBJECT hThisObject + This handle is actually the pointer of one context link point. + + return: TRUE or FALSE. + +**********************************************************************/ +BOOL +WanMgr_Dhcpv6ClientHasDelayAddedChild + ( + PDHCPCV6_CONTEXT_LINK_OBJECT hContext + ) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PDHCPCV6_CONTEXT_LINK_OBJECT pDhcpcContext = hContext; + + PSINGLE_LINK_ENTRY pSLinkEntry = (PSINGLE_LINK_ENTRY )NULL; + PCONTEXT_LINK_OBJECT pCxtLink = NULL; + + pSLinkEntry = AnscSListGetFirstEntry(&pDhcpcContext->SentOptionList); + while ( pSLinkEntry ) + { + pCxtLink = ACCESS_CONTEXT_LINK_OBJECT(pSLinkEntry); + pSLinkEntry = AnscSListGetNextEntry(pSLinkEntry); + + if ( pCxtLink->bNew ) + { + return TRUE; + } + } + return FALSE; +} diff --git a/source/WanManager/wanmgr_dhcpv6_internal.h b/source/WanManager/wanmgr_dhcpv6_internal.h new file mode 100644 index 00000000..dd5fb26c --- /dev/null +++ b/source/WanManager/wanmgr_dhcpv6_internal.h @@ -0,0 +1,220 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2015 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +/********************************************************************** + Copyright [2014] [Cisco Systems, Inc.] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +**********************************************************************/ + +#ifndef _DHCPV6_INTERNAL_H +#define _DHCPV6_INTERNAL_H + +#include "wanmgr_apis.h" +#include "wanmgr_dml_dhcpv6.h" +#include "wanmgr_dhcpv6_apis.h" +#include "wanmgr_dhcpv4_apis.h" +#include "wanmgr_rdkbus_common.h" + +/* + * This is cosa middle layer definition + * + */ +#define DHCPV6_IREP_FOLDER_NAME "Dhcpv6" +#define DHCPV6_IREP_FOLDER_NAME_CLIENT "Client" +#define DHCPV6_IREP_FOLDER_NAME_SENTOPTION "SentOption" +#define DHCPV6_IREP_FOLDER_NAME_OPTION "Option" +#define COSA_DML_RR_NAME_Dhcpv6Alias "Alias" +#define COSA_DML_RR_NAME_Dhcpv6bNew "bNew" +#define COSA_DML_RR_NAME_Dhcpv6NextInsNunmber "NextInstanceNumber" + +#define COSA_DML_DHCPV6_ALIAS 64 + +#define COSA_NAT_ROLLBACK_TEST 0 /* This is just for test purpose */ + +#define COSA_DML_DHCPV6_ACCESS_INTERVAL_CLIENTSERVER 60 /* seconds*/ +#define COSA_DML_DHCPV6_ACCESS_INTERVAL_CLIENTRECV 60 /* seconds*/ +#define COSA_DML_DHCPV6_ACCESS_INTERVAL_POOLCLIENT 10 /* seconds*/ + +/* +* This struct is only for dhcpc because it have two sub tables. +* For the two table, they just use common link struct because they havenot sub tables. +*/ +#define COSA_CONTEXT_DHCPCV6_LINK_CLASS_CONTENT \ + CONTEXT_LINK_CLASS_CONTENT \ + SLIST_HEADER SentOptionList; \ + ULONG maxInstanceOfSent; \ + PDML_DHCPCV6_SVR pServerEntry; \ + ULONG NumberOfServer; \ + ULONG PreviousVisitTimeOfServer; \ + PDML_DHCPCV6_RECV pRecvEntry; \ + ULONG NumberOfRecv; \ + ULONG PreviousVisitTimeOfRecv; \ + CHAR AliasOfSent[COSA_DML_DHCPV6_ALIAS]; \ + +typedef struct +_DHCPCV6_CONTEXT_LINK_OBJECT +{ + COSA_CONTEXT_DHCPCV6_LINK_CLASS_CONTENT +} +DHCPCV6_CONTEXT_LINK_OBJECT, *PDHCPCV6_CONTEXT_LINK_OBJECT; + +#define ACCESS_DHCPCV6_CONTEXT_LINK_OBJECT(p) \ + ACCESS_CONTAINER(p, DHCPCV6_CONTEXT_LINK_OBJECT, Linkage) \ + +/* +* This struct is for dhcp. +*/ +#define WAN_DHCPV6_DATA_CLASS_CONTENT \ + /* duplication of the base object class content */ \ + BASE_CONTENT \ + /* start of NAT object class content */ \ + SLIST_HEADER ClientList; /* This is for entry added */ \ + SLIST_HEADER PoolList; /* This is for entry added */ \ + ULONG maxInstanceOfClient; \ + ULONG maxInstanceOfPool; \ + ANSC_HANDLE hIrepFolderDhcpv6; \ + CHAR AliasOfClient[COSA_DML_DHCPV6_ALIAS]; \ + CHAR AliasOfPool[COSA_DML_DHCPV6_ALIAS]; \ + +typedef struct +_WAN_DHCPV6_DATA +{ + WAN_DHCPV6_DATA_CLASS_CONTENT +} +WAN_DHCPV6_DATA, *PWAN_DHCPV6_DATA; + + +#define DHCPV6_CLIENT_ENTRY_MATCH(src,dst) \ + (AnscEqualString((src)->Alias, (dst)->Alias, TRUE)) \ + +#define DHCPV6_CLIENT_ENTRY_MATCH2(src,dst) \ + (AnscEqualString((src), (dst), TRUE)) \ + +#define DHCPV6_SENDOPTION_ENTRY_MATCH(src,dst) \ + (AnscEqualString((src)->Alias, (dst)->Alias, TRUE)) \ + +#define DHCPV6_SENDOPTION_ENTRY_MATCH2(src,dst) \ + (AnscEqualString((src), (dst), TRUE)) \ + +#define DHCPV6_REQOPTION_ENTRY_MATCH(src,dst) \ + (AnscEqualString((src)->Alias, (dst)->Alias, TRUE)) \ + +#define DHCPV6_REQOPTION_ENTRY_MATCH2(src,dst) \ + (AnscEqualString((src), (dst), TRUE)) \ + +#define DHCPV6_CLIENT_INITIATION_CONTEXT(pDhcpc) \ + CONTEXT_LINK_INITIATION_CONTENT(((PCONTEXT_LINK_OBJECT)(pDhcpc))) \ + AnscSListInitializeHeader(&(pDhcpc)->SentOptionList); \ + (pDhcpc)->maxInstanceOfSent = 0; \ + (pDhcpc)->pServerEntry = NULL; \ + (pDhcpc)->NumberOfServer = 0; \ + (pDhcpc)->PreviousVisitTimeOfServer = 0; \ + (pDhcpc)->pRecvEntry = NULL; \ + (pDhcpc)->NumberOfRecv = 0; \ + (pDhcpc)->PreviousVisitTimeOfRecv = 0; \ + AnscZeroMemory((pDhcpc)->AliasOfSent, sizeof((pDhcpc)->AliasOfSent) ); \ + +#define DHCPV6_CLIENT_SET_DEFAULTVALUE(pDhcpc) \ + (pDhcpc)->Cfg.bEnabled = FALSE; \ + AnscZeroMemory((pDhcpc)->Cfg.Interface, sizeof((pDhcpc)->Cfg.Interface)); \ + (pDhcpc)->Info.Status = DML_DHCP_STATUS_Disabled; \ + +#define DHCPV6_SENTOPTION_SET_DEFAULTVALUE(pSentOption) \ + (pSentOption)->bEnabled = FALSE; \ + (pSentOption)->Tag = 0; \ + AnscZeroMemory( (pSentOption)->Value, sizeof( (pSentOption)->Value ) ); \ + +/* + Function declaration +*/ + +ANSC_HANDLE +WanMgr_Dhcpv6Create + ( + VOID + ); + +ANSC_STATUS +WanMgr_Dhcpv6Initialize + ( + ANSC_HANDLE hThisObject + ); + +ANSC_STATUS +WanMgr_Dhcpv6Remove + ( + ANSC_HANDLE hThisObject + ); + +ANSC_STATUS +WanMgr_Dhcpv6RegGetDhcpv6Info + ( + ANSC_HANDLE hThisObject + ); + +ANSC_STATUS +WanMgr_Dhcpv6RegSetDhcpv6Info + ( + ANSC_HANDLE hThisObject + ); + +BOOL +WanMgr_Dhcpv6ClientHasDelayAddedChild + ( + PDHCPCV6_CONTEXT_LINK_OBJECT hContext + ); + +ANSC_STATUS +WanMgr_Dhcpv6BackendGetDhcpv6Info + ( + ANSC_HANDLE hThisObject + ); + +BOOL +WanMgr_DmlSetIpaddr + ( + PULONG pIPAddr, + PCHAR pString, + ULONG MaxNumber + ); + +BOOL +WanMgr_DmlGetIpaddrString + ( + PUCHAR pString, + PULONG pulStrLength, + PULONG pIPAddr, + ULONG MaxNumber + ); + + +#endif + + diff --git a/source/WanManager/wanmgr_interface_sm.c b/source/WanManager/wanmgr_interface_sm.c new file mode 100644 index 00000000..f7fc4210 --- /dev/null +++ b/source/WanManager/wanmgr_interface_sm.c @@ -0,0 +1,2015 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2015 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +#include +#include +#include +#include "wanmgr_interface_sm.h" +#include "wanmgr_utils.h" +#include "platform_hal.h" +#include "wanmgr_sysevents.h" +#include "wanmgr_ipc.h" +#include "wanmgr_rdkbus_utils.h" +#include "wanmgr_data.h" +#include "wanmgr_interface_sm.h" +#include "wanmgr_platform_events.h" +#include "wanmgr_net_utils.h" +#include "wanmgr_dhcpv4_apis.h" +#include "wanmgr_dhcpv6_apis.h" + +typedef enum +{ + WAN_STATE_EXIT = 0, + WAN_STATE_CONFIGURING_WAN, + WAN_STATE_VALIDATING_WAN, + WAN_STATE_OBTAINING_IP_ADDRESSES, + WAN_STATE_IPV4_LEASED, + WAN_STATE_IPV6_LEASED, + WAN_STATE_DUAL_STACK_ACTIVE, + WAN_STATE_IPV4_OVER_IPV6_ACTIVE, + WAN_STATE_REFRESHING_WAN, + WAN_STATE_DECONFIGURING_WAN +} eWanState_t; + +#define LOOP_TIMEOUT 50000 // timeout in milliseconds. This is the state machine loop interval + +/*WAN Manager States*/ +static eWanState_t wan_state_configuring_wan(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl); +static eWanState_t wan_state_validating_wan(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl); +static eWanState_t wan_state_obtaining_ip_addresses(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl); +static eWanState_t wan_state_ipv4_leased(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl); +static eWanState_t wan_state_ipv6_leased(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl); +static eWanState_t wan_state_dual_stack_active(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl); +static eWanState_t wan_state_ipv4_over_ipv6_active(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl); +static eWanState_t wan_state_refreshing_wan(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl); +static eWanState_t wan_state_deconfiguring_wan(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl); +static eWanState_t wan_state_exit(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl); + +/*WAN Manager Transitions*/ +static eWanState_t wan_transition_start(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl); +static eWanState_t wan_transition_physical_interface_down(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl); +static eWanState_t wan_transition_wan_up(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl); +static eWanState_t wan_transition_wan_validated(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl); +static eWanState_t wan_transition_refreshing_wan(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl); +static eWanState_t wan_transition_wan_refreshed(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl); +static eWanState_t wan_transition_ipv4_up(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl); +static eWanState_t wan_transition_ipv4_down(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl); +static eWanState_t wan_transition_ipv6_up(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl); +static eWanState_t wan_transition_ipv6_down(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl); +static eWanState_t wan_transition_dual_stack_down(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl); +static eWanState_t wan_transition_ipv4_over_ipv6_up(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl); +static eWanState_t wan_transition_ipv4_over_ipv6_down(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl); +static eWanState_t wan_transition_exit(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl); + +/******************************************************************************** + * @brief Configure IPV4 configuration on the interface. + * This API calls the HAL routine to configure ipv4. + * @param ifname Wan interface name + * @param wanData pointer to WanData_t holds the wan data + * @return RETURN_OK upon success else returned error code. + *********************************************************************************/ +static int wan_setUpIPv4(DML_WAN_IFACE* pInterface); + +/******************************************************************************** + * @brief Unconfig IPV4 configuration on the interface. + * This API calls the HAL routine to unconfig ipv4. + * @param ifname Wan interface name + * @param wanData pointer to WanData_t holds the wan data + * @return RETURN_OK upon success else returned error code. + *********************************************************************************/ +static int wan_tearDownIPv4(DML_WAN_IFACE* pInterface); + +/************************************************************************************* + * @brief Configure IPV6 configuration on the interface. + * This API calls the HAL routine to config ipv6. + * @param ifname Wan interface name + * @param wanData pointer to WanData_t holds the wan data + * @return RETURN_OK upon success else returned error code. + **************************************************************************************/ +static int wan_setUpIPv6(DML_WAN_IFACE* pInterface); + +/************************************************************************************* + * @brief Unconfig IPV6 configuration on the interface. + * This API calls the HAL routine to unconfig ipv6. + * @param ifname Wan interface name + * @param wanData pointer to WanData_t holds the wan data + * @return RETURN_OK upon success else returned error code. + **************************************************************************************/ +static int wan_tearDownIPv6(DML_WAN_IFACE* pInterface); + +/************************************************************************************** + * @brief Update DNS configuration into /etc/resolv.conf + * @param wanIfname wan interface name + * @param addIPv4 boolean flag indicates whether IPv4 DNS data needs to be update + * @param addIPv6 boolean flag indicates whether IPv6 DNS data needs to be update + * @return RETURN_OK upon success else ERROR code returned + **************************************************************************************/ +static int wan_updateDNS(DML_WAN_IFACE* pInterface, BOOL addIPv4, BOOL addIPv6); + +/************************************************************************************** + * @brief Clear the DHCP client data stored. + * It should be used to clear the old data before start a new DHCP client. + * @param Interface data structure + * @return ANSC_STATUS_SUCCESS upon success else ANSC_STATUS_FAILURE + **************************************************************************************/ +static ANSC_STATUS WanManager_ClearDHCPData(DML_WAN_IFACE* pInterface); + +#ifdef FEATURE_MAPT +/************************************************************************************* + * @brief Enable mapt configuration on the interface. + * This API calls the HAL routine to Enable mapt. + * @param ifname Wan interface name + * @return RETURN_OK upon success else ERROR code returned + **************************************************************************************/ +static int wan_setUpMapt(const char *ifName); + +/************************************************************************************* + * @brief Disable mapt configuration on the interface. + * This API calls the HAL routine to disable mapt. + * @param ifname Wan interface name + * @return RETURN_OK upon success else ERROR code returned + **************************************************************************************/ +static int wan_tearDownMapt(const char *ifName); +#endif //FEATURE_MAPT +/************************************************************************************* + * @brief Check IPv6 address assigned to interface or not. + * This API internally checks ipv6 prefix being set, received valid gateway and + * lan ipv6 address ready to use. + * @return RETURN_OK on success else RETURN_ERR + *************************************************************************************/ +static int checkIpv6AddressAssignedToBridge(); + +/************************************************************************************* + * @brief Check IPv6 address is ready to use or not + * @return RETURN_OK on success else RETURN_ERR + *************************************************************************************/ +static int checkIpv6LanAddressIsReadyToUse(); + +/************************************************************************************* + * @brief Check CPE received a valid IPv6 gw address + * @return RETURN_OK on success else RETURN_ERR + ************************************************************************************/ +static int validate_v6_gateway_address(void); + +/************************************************************************************ + * @brief Set v6 prefixe required for lan configuration + * @return RETURN_OK on success else RETURN_ERR + ************************************************************************************/ +static int setUpLanPrefixIPv6(DML_WAN_IFACE* pIfaceData); + + + +#ifdef FEATURE_MAPT +static int wan_setUpMapt(const char *ifName) +{ + int ret = RETURN_OK; + + if (ifName == NULL) + { + CcspTraceError(("%s %d - Invalid memory \n", __FUNCTION__, __LINE__)); + return RETURN_ERR; + } + + /* Disable flow cache. */ + if (WanManager_DoSystemActionWithStatus("wanmanager", "fcctl disable") != RETURN_OK) + { + CcspTraceError(("%s %d - wanmanager: Failed to disable packet accelaration \n ", __FUNCTION__, __LINE__)); + ret = RETURN_ERR; + } + + if (WanManager_DoSystemActionWithStatus("wanmanager", "fcctl flush") != RETURN_OK) + { + CcspTraceError(("%s %d - wanmanager: Failed to flush the cache \n", __FUNCTION__, __LINE__)); + ret = RETURN_ERR; + } + + /* Disable runner. */ + if (WanManager_DoSystemActionWithStatus("wanmanager", "runner disable") != RETURN_OK) + { + CcspTraceError(("%s %d - wanmanager: Failed to disable the runner \n", __FUNCTION__, __LINE__)); + ret = RETURN_ERR; + } + + if (WanManager_DoSystemActionWithStatus("wanmanager", "insmod /lib/modules/`uname -r`/extra/ivi.ko") != RETURN_OK) + { + CcspTraceError(("%s %d -insmod: Failed to add ivi.ko \n", __FUNCTION__, __LINE__)); + ret = RETURN_ERR; + } + + return ret; +} + +static int wan_tearDownMapt(const char *ifName) +{ + int ret = RETURN_OK; + FILE *file; + char line[BUFLEN_64]; + + if (ifName == NULL) + { + CcspTraceError(("%s %d - Invalid memory \n", __FUNCTION__, __LINE__)); + return RETURN_ERR; + } + + file = popen("cat /proc/modules | grep ivi","r"); + if( file == NULL) + { + CcspTraceError(("[%s][%d]Failed to open /proc/modules \n", __FUNCTION__, __LINE__)); + ret = RETURN_ERR; + } + else + { + if( fgets (line, BUFLEN_64, file) !=NULL ) { + if( strstr(line, "ivi")) { + if (WanManager_DoSystemActionWithStatus("wanmanager", "ivictl -q") != RETURN_OK) + { + CcspTraceError(("%s %d ivictl: Failed to stop \n", __FUNCTION__, __LINE__)); + } + else + { + CcspTraceError(("%s %d ivictl stopped successfully\n", __FUNCTION__, __LINE__)); + } + + if (WanManager_DoSystemActionWithStatus("wanmanager", "rmmod -f /lib/modules/`uname -r`/extra/ivi.ko") != RETURN_OK) + { + CcspTraceError(("%s %d rmmod: Failed to remove ivi.ko \n", __FUNCTION__, __LINE__)); + } + else + { + CcspTraceError(("%s %d ivi.ko removed\n", __FUNCTION__, __LINE__)); + } + } + } + pclose(file); + } + + /* Enable packet accelaration. */ + if (WanManager_DoSystemActionWithStatus("wanmanager", "fcctl enable") != RETURN_OK) + { + CcspTraceError(("%s %dwanmanager: Failed to enable packet accelaration \n ", __FUNCTION__, __LINE__)); + ret = RETURN_ERR; + } + + /* Enable runner. */ + if (WanManager_DoSystemActionWithStatus("wanmanager", "runner enable") != RETURN_OK) + { + CcspTraceError(("%s %d wanmanager: Failed to enable the runner \n ", __FUNCTION__, __LINE__)); + ret = RETURN_ERR; + } + + return ret; +} +#endif + + + +/*********************************************************************************/ +/**************************** ACTIONS ********************************************/ +/*********************************************************************************/ +void WanManager_UpdateInterfaceStatus(DML_WAN_IFACE* pIfaceData, wanmgr_iface_status_t iface_status) +{ + CcspTraceInfo(("ifName: %s, link: %s, ipv4: %s, ipv6: %s\n", ((pIfaceData != NULL) ? pIfaceData->Wan.Name : "NULL"), + ((iface_status == WANMGR_IFACE_LINK_UP) ? "UP" : (iface_status == WANMGR_IFACE_LINK_DOWN) ? "DOWN" : "N/A"), + ((iface_status == WANMGR_IFACE_CONNECTION_UP) ? "UP" : (iface_status == WANMGR_IFACE_CONNECTION_DOWN) ? "DOWN" : "N/A"), + ((iface_status == WANMGR_IFACE_CONNECTION_IPV6_UP) ? "UP" : (iface_status == WANMGR_IFACE_CONNECTION_IPV6_DOWN) ? "DOWN" : "N/A") + )); + + if(pIfaceData == NULL) + { + return; + } + +#ifdef FEATURE_MAPT + CcspTraceInfo(("mapt: %s \n", + ((iface_status == WANMGR_IFACE_MAPT_START) ? "UP" : (iface_status == WANMGR_IFACE_MAPT_STOP) ? "DOWN" : "N/A"))); +#endif + + switch (iface_status) + { + case WANMGR_IFACE_LINK_UP: + { + break; + } + case WANMGR_IFACE_LINK_DOWN: + { + break; + } + case WANMGR_IFACE_CONNECTION_UP: + { + pIfaceData->IP.Ipv4Status = WAN_IFACE_IPV4_STATE_UP; + break; + } + case WANMGR_IFACE_CONNECTION_DOWN: + { + pIfaceData->IP.Ipv4Status = WAN_IFACE_IPV4_STATE_DOWN; + pIfaceData->IP.Ipv4Changed = FALSE; + strncpy(pIfaceData->IP.Ipv4Data.ip, "", sizeof(pIfaceData->IP.Ipv4Data.ip)); + wanmgr_sysevents_ipv4Info_init(pIfaceData->Wan.Name); // reset the sysvent/syscfg fields + break; + } + case WANMGR_IFACE_CONNECTION_IPV6_UP: + { + pIfaceData->IP.Ipv6Status = WAN_IFACE_IPV6_STATE_UP; + break; + } + case WANMGR_IFACE_CONNECTION_IPV6_DOWN: + { + pIfaceData->IP.Ipv6Status = WAN_IFACE_IPV6_STATE_DOWN; + pIfaceData->IP.Ipv6Changed = FALSE; + pIfaceData->MAP.MaptStatus = WAN_IFACE_MAPT_STATE_DOWN; // reset MAPT flag + pIfaceData->MAP.MaptChanged = FALSE; // reset MAPT flag + strncpy(pIfaceData->IP.Ipv6Data.address, "", sizeof(pIfaceData->IP.Ipv6Data.address)); + strncpy(pIfaceData->IP.Ipv6Data.pdIfAddress, "", sizeof(pIfaceData->IP.Ipv6Data.pdIfAddress)); + strncpy(pIfaceData->IP.Ipv6Data.sitePrefix, "", sizeof(pIfaceData->IP.Ipv6Data.sitePrefix)); + strncpy(pIfaceData->IP.Ipv6Data.nameserver, "", sizeof(pIfaceData->IP.Ipv6Data.nameserver)); + strncpy(pIfaceData->IP.Ipv6Data.nameserver1, "", sizeof(pIfaceData->IP.Ipv6Data.nameserver1)); + wanmgr_sysevents_ipv6Info_init(); // reset the sysvent/syscfg fields + break; + } +#ifdef FEATURE_MAPT + case WANMGR_IFACE_MAPT_START: + { + pIfaceData->MAP.MaptStatus = WAN_IFACE_MAPT_STATE_DUP; + break; + } + case WANMGR_IFACE_MAPT_STOP: + { + pIfaceData->MAP.MaptStatus = WAN_IFACE_MAPT_STATE_DOWN; // reset MAPT flag + pIfaceData->MAP.MaptChanged = FALSE; // reset MAPT flag + break; + } +#endif + default: + /* do nothing */ + break; + } + + return; +} + +static ANSC_STATUS WanMgr_Send_InterfaceRefresh(DML_WAN_IFACE* pInterface) +{ + DML_WAN_IFACE* pWanIface4Thread = NULL; + pthread_t refreshThreadId; + INT iErrorCode = -1; + + if(pInterface == NULL) + { + return ANSC_STATUS_FAILURE; + } + + if((pInterface->Wan.Refresh == TRUE) && + (pInterface->Wan.LinkStatus == WAN_IFACE_LINKSTATUS_UP)) + { + //Allocate memory for interface struct + pWanIface4Thread = (DML_WAN_IFACE*)malloc(sizeof(DML_WAN_IFACE)); + if( NULL == pWanIface4Thread ) + { + CcspTraceError(("%s %d Failed to allocate memory\n", __FUNCTION__, __LINE__)); + return ANSC_STATUS_FAILURE; + } + + //Copy WAN interface structure for thread + memset( pWanIface4Thread, 0, sizeof(DML_WAN_IFACE)); + memcpy( pWanIface4Thread, pInterface, sizeof(DML_WAN_IFACE) ); + + //WAN refresh thread + iErrorCode = pthread_create( &refreshThreadId, NULL, &WanMgr_RdkBus_WanIfRefreshThread, (void*)pWanIface4Thread ); + if( 0 != iErrorCode ) + { + CcspTraceInfo(("%s %d - Failed to start WAN refresh thread EC:%d\n", __FUNCTION__, __LINE__, iErrorCode )); + return ANSC_STATUS_FAILURE; + } + } + + return ANSC_STATUS_SUCCESS; +} + +static int wan_updateDNS(DML_WAN_IFACE* pInterface, BOOL addIPv4, BOOL addIPv6) +{ + int ret = RETURN_OK; + DnsData_t dnsData; + + if (NULL == pInterface) + { + CcspTraceError(("%s %d - Invalid memory \n", __FUNCTION__, __LINE__)); + return RETURN_ERR; + } + + memset(&dnsData, 0, sizeof(DnsData_t)); + + if (addIPv4) + { + strncpy(dnsData.dns_ipv4_1, pInterface->IP.Ipv4Data.dnsServer, sizeof(dnsData.dns_ipv4_1)); + strncpy(dnsData.dns_ipv4_2, pInterface->IP.Ipv4Data.dnsServer1, sizeof(dnsData.dns_ipv4_2)); + } + + if (addIPv6) + { + strncpy(dnsData.dns_ipv6_1, pInterface->IP.Ipv6Data.nameserver, sizeof(dnsData.dns_ipv6_1)); + strncpy(dnsData.dns_ipv6_2, pInterface->IP.Ipv6Data.nameserver1, sizeof(dnsData.dns_ipv6_2)); + } + + if ((ret = WanManager_CreateResolvCfg(&dnsData)) != RETURN_OK) + { + CcspTraceError(("%s %d - Failed to set up DNS servers \n", __FUNCTION__, __LINE__)); + } + else + { + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_DHCP_SERVER_RESTART, NULL, 0); + } + + return ret; +} + +static int validate_v6_gateway_address(void) +{ + char command[BUFLEN_64] = {0}; + char line[BUFLEN_128] = {0}; + char defaultGateway[BUFLEN_64] = {0}; + int defaultGatewayLen = 64; + FILE *fp; + int ret = RETURN_OK; + + snprintf(command, sizeof(command), "ip -6 route show default | grep default | awk '{print $3}'"); + + fp = popen(command, "r"); + + if (fp) + { + if (fgets(line, sizeof(line), fp) != NULL) + { + char *token = strtok(line, "\n"); // get string up until newline character + if (token) + { + strncpy(defaultGateway, token, defaultGatewayLen); + CcspTraceInfo(("IPv6 Default Gateway Address = %s \n", defaultGateway)); + } + else + { + CcspTraceError(("Could not parse IPv6 Gateway Address \n")); + ret = RETURN_ERR; + } + } + else + { + ret = RETURN_ERR; + } + pclose(fp); + } + else + { + CcspTraceError(("Failed to get the default Gateway Address \n")); + ret = RETURN_ERR; + } + + return ret; +} + +static int checkIpv6LanAddressIsReadyToUse() +{ + char buffer[BUFLEN_256] = {0}; + FILE *fp_dad = NULL; + FILE *fp_route = NULL; + int address_flag = 0; + int dad_flag = 0; + int route_flag = 0; + struct ifaddrs *ifap = NULL; + struct ifaddrs *ifa = NULL; + char addr[INET6_ADDRSTRLEN] = {0}; + int i; + + /* We need to check the interface has got an IPV6-prefix , beacuse P-and-M can send + the same event when interface is down, so we ensure send the UP event only + when interface has an IPV6-prefix. + */ + if (!getifaddrs(&ifap)) { + for (ifa = ifap; ifa; ifa = ifa->ifa_next) { + if(strncmp(ifa->ifa_name,ETH_BRIDGE_NAME, strlen(ETH_BRIDGE_NAME))) + continue; + if (ifa->ifa_addr->sa_family != AF_INET6) + continue; + getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in6), addr, + sizeof(addr), NULL, 0, NI_NUMERICHOST); + if((strncmp(addr + (strlen(addr) - 3), "::1", 3) == 0)){ + address_flag = 1; + break; + } + }//for loop + freeifaddrs(ifap); + }//getifaddr close + + if(address_flag == 0) { + return -1; + } + /* Check Duplicate Address Detection (DAD) status. The way it works is that + after an address is added to an interface, the operating system uses the + Neighbor Discovery Protocol to check if any other host on the network + has the same address. The whole process will take around 3 to 4 seconds + to complete. Also we need to check and ensure that the gateway has + a valid default route entry. + */ + for(i=0; i<15; i++) { + buffer[0] = '\0'; + if(dad_flag == 0) { + if ((fp_dad = popen("ip address show dev brlan0 tentative", "r"))) { + if(fp_dad != NULL) { + fgets(buffer, BUFLEN_256, fp_dad); + if(strlen(buffer) == 0 ) { + dad_flag = 1; + } + pclose(fp_dad); + } + } + } + + if(route_flag == 0) { + buffer[0] = '\0'; + if ((fp_route = popen("ip -6 ro | grep default", "r"))) { + if(fp_route != NULL) { + fgets(buffer, BUFLEN_256, fp_route); + if(strlen(buffer) > 0 ) { + route_flag = 1; + } + pclose(fp_route); + } + } + } + + if(dad_flag == 0 || route_flag == 0) { + sleep(1); + } + else { + break; + } + } + + if(dad_flag == 0 || route_flag == 0) { + return -1; + } + + return 0; +} + +static int checkIpv6AddressAssignedToBridge() +{ + char lanPrefix[BUFLEN_128] = {0}; + int ret = RETURN_ERR; + + sysevent_get(sysevent_fd, sysevent_token, SYSEVENT_GLOBAL_IPV6_PREFIX_SET, lanPrefix, sizeof(lanPrefix)); + + if(strlen(lanPrefix) > 0) + { + if ((validate_v6_gateway_address() == RETURN_OK) && (checkIpv6LanAddressIsReadyToUse() == 0)) + { + ret = RETURN_OK; + } + } + + return ret; +} + +static int setUpLanPrefixIPv6(DML_WAN_IFACE* pIfaceData) +{ + if (pIfaceData == NULL) + { + CcspTraceError(("%s %d - Invalid memory \n", __FUNCTION__, __LINE__)); + return RETURN_ERR; + } + + int index = strcspn(pIfaceData->IP.Ipv6Data.sitePrefix, "/"); + if (index < strlen(pIfaceData->IP.Ipv6Data.sitePrefix)) + { + char lanPrefix[BUFLEN_48] = {0}; + strncpy(lanPrefix, pIfaceData->IP.Ipv6Data.sitePrefix, index); + if ((sizeof(lanPrefix) - index) > 3) + { + char previousPrefix[BUFLEN_48] = {0}; + char previousPrefix_vldtime[BUFLEN_48] = {0}; + char previousPrefix_prdtime[BUFLEN_48] = {0}; + strncat(lanPrefix, "/64", 3); + sysevent_get(sysevent_fd, sysevent_token, SYSEVENT_FIELD_IPV6_PREFIX, previousPrefix, sizeof(previousPrefix)); + sysevent_get(sysevent_fd, sysevent_token, SYSEVENT_FIELD_IPV6_PREFIXVLTIME, previousPrefix_vldtime, sizeof(previousPrefix_vldtime)); + sysevent_get(sysevent_fd, sysevent_token, SYSEVENT_FIELD_IPV6_PREFIXPLTIME, previousPrefix_prdtime, sizeof(previousPrefix_prdtime)); + if (strncmp(previousPrefix, lanPrefix, BUFLEN_48) == 0) + { + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_FIELD_PREVIOUS_IPV6_PREFIX, "", 0); + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_FIELD_PREVIOUS_IPV6_PREFIXVLTIME, "0", 0); + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_FIELD_PREVIOUS_IPV6_PREFIXPLTIME, "0", 0); + } + else if (strncmp(previousPrefix, "", BUFLEN_48) != 0) + { + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_FIELD_PREVIOUS_IPV6_PREFIX, previousPrefix, 0); + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_FIELD_PREVIOUS_IPV6_PREFIXVLTIME, previousPrefix_vldtime, 0); + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_FIELD_PREVIOUS_IPV6_PREFIXPLTIME, previousPrefix_prdtime, 0); + } + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_FIELD_IPV6_PREFIX, lanPrefix, 0); + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_FIELD_TR_EROUTER_DHCPV6_CLIENT_PREFIX, lanPrefix, 0); + } + } + + return RETURN_OK; +} + + +static int wan_setUpIPv4(DML_WAN_IFACE* pInterface) +{ + int ret = RETURN_OK; + char cmdStr[BUFLEN_128 + IP_ADDR_LENGTH] = {0}; + char bCastStr[IP_ADDR_LENGTH] = {0}; + char line[BUFLEN_64] = {0}; + char *cp = NULL; + FILE *fp = NULL; + + if (pInterface == NULL) + { + CcspTraceError(("%s %d - Invalid memory \n", __FUNCTION__, __LINE__)); + return RETURN_ERR; + } + if (RETURN_OK == wan_updateDNS(pInterface, TRUE, (pInterface->IP.Ipv6Status == WAN_IFACE_IPV6_STATE_UP))) + { + CcspTraceInfo(("%s %d - IPv4 DNS servers configures successfully \n", __FUNCTION__, __LINE__)); + /* DHCP restart triggered. */ + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_DHCP_SERVER_RESTART, NULL, 0); + } + else + { + CcspTraceInfo(("%s %d - Failed to configure IPv4 DNS servers \n", __FUNCTION__, __LINE__)); + } + + /** Setup IPv4: such as + * "ifconfig eth0 10.6.33.165 netmask 255.255.255.192 broadcast 10.6.33.191 up" + */ + if (WanManager_GetBCastFromIpSubnetMask(pInterface->IP.Ipv4Data.ip, pInterface->IP.Ipv4Data.mask, bCastStr) != RETURN_OK) + { + CcspTraceError((" %s %d - bad address %s/%s \n",__FUNCTION__,__LINE__, pInterface->IP.Ipv4Data.ip, pInterface->IP.Ipv4Data.mask)); + return RETURN_ERR; + } + + snprintf(cmdStr, sizeof(cmdStr), "ifconfig %s %s netmask %s broadcast %s", + pInterface->IP.Ipv4Data.ifname, pInterface->IP.Ipv4Data.ip, pInterface->IP.Ipv4Data.mask, bCastStr); + CcspTraceInfo(("%s %d - IP configuration = %s \n", __FUNCTION__, __LINE__, cmdStr)); + WanManager_DoSystemAction("setupIPv4:", cmdStr); + + snprintf(cmdStr, sizeof(cmdStr), "sendarp -s %s -d %s", ETH_BRIDGE_NAME, ETH_BRIDGE_NAME); + WanManager_DoSystemAction("setupIPv4", cmdStr); + + /** Need to manually add route if the connection is PPP connection*/ + if (pInterface->PPP.Enable == TRUE) + { + if (WanManager_AddGatewayRoute(&pInterface->IP.Ipv4Data) != RETURN_OK) + { + CcspTraceError(("%s %d - Failed to set up system gateway", __FUNCTION__, __LINE__)); + } + } + + /** Set default gatway. */ + if (WanManager_AddDefaultGatewayRoute(&pInterface->IP.Ipv4Data) != RETURN_OK) + { + CcspTraceError(("%s %d - Failed to set up default system gateway", __FUNCTION__, __LINE__)); + } + + /** Update required sysevents. */ + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_IPV4_CONNECTION_STATE, WAN_STATUS_UP, 0); + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_CURRENT_IPV4_LINK_STATE, WAN_STATUS_UP, 0); + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_CURRENT_WAN_IPADDR, pInterface->IP.Ipv4Data.ip, 0); + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_CURRENT_WAN_SUBNET, pInterface->IP.Ipv4Data.mask, 0); + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_CURRENT_WAN_STATE, WAN_STATUS_UP, 0); + if ((fp = fopen("/proc/uptime", "rb")) == NULL) + { + return RETURN_ERR; + } + if (fgets(line, sizeof(line), fp) != NULL) + { + if ((cp = strchr(line, ',')) != NULL) + *cp = '\0'; + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_WAN_START_TIME, line, 0); + } + fclose(fp); + + if (strstr(pInterface->Phy.Path, "Ethernet")) + { + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_ETHWAN_INITIALIZED, "1", 0); + } + if (pInterface->IP.Ipv6Status == WAN_IFACE_IPV6_STATE_DOWN) + { + int uptime = 0; + char buffer[64] = {0}; + + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_WAN_STATUS, WAN_STATUS_STARTED, 0); + CcspTraceInfo(("%s %d - wan-status event set to started \n", __FUNCTION__, __LINE__)); + + //Get WAN uptime + WanManager_GetDateAndUptime( buffer, &uptime ); + LOG_CONSOLE("%s Wan_init_complete:%d\n",buffer,uptime); + + system("print_uptime \"boot_to_wan_uptime\""); + } + + /* Firewall restart. */ + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_FIREWALL_RESTART, NULL, 0); + return ret; +} + + +static int wan_tearDownIPv4(DML_WAN_IFACE* pInterface) +{ + int ret = RETURN_OK; + char cmdStr[BUFLEN_64] = {0}; + + if (pInterface == NULL) + { + CcspTraceError(("%s %d - Invalid memory \n", __FUNCTION__, __LINE__)); + return RETURN_ERR; + } + + /** Reset IPv4 DNS configuration. */ + if (RETURN_OK == wan_updateDNS(pInterface, FALSE, (pInterface->IP.Ipv6Status == WAN_IFACE_IPV6_STATE_UP))) + { + CcspTraceInfo(("%s %d - IPv4 DNS servers unconfig successfully \n", __FUNCTION__, __LINE__)); + /* DHCP restart trigger. */ + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_DHCP_SERVER_RESTART, NULL, 0); + } + else + { + CcspTraceError(("%s %d - Failed to unconfig IPv4 DNS servers \n", __FUNCTION__, __LINE__)); + ret = RETURN_ERR; + } + + /* Need to remove the network from the routing table by + * doing "ifconfig L3IfName 0.0.0.0" + * wanData->ipv4Data.ifname is Empty. + */ + snprintf(cmdStr, sizeof(cmdStr), "ifconfig %s 0.0.0.0", pInterface->Wan.Name); + if (WanManager_DoSystemActionWithStatus("wan_tearDownIPv4: ifconfig L3IfName 0.0.0.0", (cmdStr)) != 0) + { + CcspTraceError(("%s %d - failed to run cmd: %s", __FUNCTION__, __LINE__, cmdStr)); + ret = RETURN_ERR; + } + + /* ReSet the required sysevents. */ + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_IPV4_CONNECTION_STATE, WAN_STATUS_DOWN, 0); + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_CURRENT_IPV4_LINK_STATE, WAN_STATUS_DOWN, 0); + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_CURRENT_WAN_STATE, WAN_STATUS_DOWN, 0); + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_WAN_START_TIME, "0", 0); + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_CURRENT_WAN_IPADDR, "0.0.0.0", 0); + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_CURRENT_WAN_SUBNET, "255.255.255.0", 0); + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_FIREWALL_RESTART, NULL, 0); + if (strstr(pInterface->Phy.Path, "Ethernet")) + { + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_ETHWAN_INITIALIZED, "0", 0); + } + + if (pInterface->IP.Ipv6Status == WAN_IFACE_IPV6_STATE_DOWN) + { + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_WAN_STATUS, WAN_STATUS_STOPPED, 0); + CcspTraceInfo(("%s %d - wan-status event set to stopped \n", __FUNCTION__, __LINE__)); + } + + return ret; +} + + +static int wan_setUpIPv6(DML_WAN_IFACE* pInterface) +{ + int ret = RETURN_OK; + + if (pInterface == NULL) + { + CcspTraceError(("%s %d - Invalid memory \n", __FUNCTION__, __LINE__)); + return RETURN_ERR; + } + + /** Reset IPv6 DNS configuration. */ + if (RETURN_OK == wan_updateDNS(pInterface, (pInterface->IP.Ipv4Status == WAN_IFACE_IPV4_STATE_UP), TRUE)) + { + CcspTraceInfo(("%s %d - IPv6 DNS servers configured successfully \n", __FUNCTION__, __LINE__)); + /* DHCP restart trigger. */ + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_DHCP_SERVER_RESTART, NULL, 0); + } + else + { + CcspTraceError(("%s %d - Failed to configure IPv6 DNS servers \n", __FUNCTION__, __LINE__)); + ret = RETURN_ERR; + } + + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_IPV6_CONNECTION_STATE, WAN_STATUS_UP, 0); + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_RADVD_RESTART, NULL, 0); + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_DHCP_SERVER_RESTART, NULL, 0); + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_FIREWALL_RESTART, NULL, 0); + + if (pInterface->IP.Ipv4Status == WAN_IFACE_IPV4_STATE_DOWN) + { + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_WAN_STATUS, WAN_STATUS_STARTED, 0); + CcspTraceInfo(("%s %d - wan-status event set to started \n", __FUNCTION__, __LINE__)); + } + + return ret; +} + +static int wan_tearDownIPv6(DML_WAN_IFACE* pInterface) +{ + int ret = RETURN_OK; + + if (pInterface == NULL) + { + CcspTraceError(("%s %d - Invalid memory \n", __FUNCTION__, __LINE__)); + return RETURN_ERR; + } + + /** Reset IPv6 DNS configuration. */ + if (RETURN_OK == wan_updateDNS(pInterface, (pInterface->IP.Ipv4Status == WAN_IFACE_IPV4_STATE_UP), FALSE)) + { + CcspTraceInfo(("%s %d - IPv6 DNS servers unconfig successfully \n", __FUNCTION__, __LINE__)); + /* DHCP restart trigger. */ + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_DHCP_SERVER_RESTART, NULL, 0); + } + else + { + CcspTraceError(("%s %d - Failed to unconfig IPv6 DNS servers \n", __FUNCTION__, __LINE__)); + } + + /** Unconfig IPv6. */ + if ( WanManager_Ipv6AddrUtil(ETH_BRIDGE_NAME,DEL_ADDR,0,0) < 0) + { + AnscTraceError(("%s %d - Failed to remove inactive address \n", __FUNCTION__,__LINE__)); + } + + // Reset sysvevents. + char previousPrefix[BUFLEN_48] = {0}; + char previousPrefix_vldtime[BUFLEN_48] = {0}; + char previousPrefix_prdtime[BUFLEN_48] = {0}; + /* set ipv6 down sysevent notification. */ + sysevent_get(sysevent_fd, sysevent_token, SYSEVENT_FIELD_IPV6_PREFIX, previousPrefix, sizeof(previousPrefix)); + sysevent_get(sysevent_fd, sysevent_token, SYSEVENT_FIELD_IPV6_PREFIXVLTIME, previousPrefix_vldtime, sizeof(previousPrefix_vldtime)); + sysevent_get(sysevent_fd, sysevent_token, SYSEVENT_FIELD_IPV6_PREFIXPLTIME, previousPrefix_prdtime, sizeof(previousPrefix_prdtime)); + if (strncmp(previousPrefix, "", BUFLEN_48) != 0) + { + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_FIELD_PREVIOUS_IPV6_PREFIX, previousPrefix, 0); + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_FIELD_PREVIOUS_IPV6_PREFIXVLTIME, previousPrefix_vldtime, 0); + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_FIELD_PREVIOUS_IPV6_PREFIXPLTIME, previousPrefix_prdtime, 0); + } + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_FIELD_IPV6_PREFIX, "", 0); + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_FIELD_TR_EROUTER_DHCPV6_CLIENT_PREFIX, "", 0); + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_IPV6_CONNECTION_STATE, WAN_STATUS_DOWN, 0); + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_FIREWALL_RESTART, NULL, 0); + + if (pInterface->IP.Ipv4Status == WAN_IFACE_IPV4_STATE_DOWN) + { + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_WAN_STATUS, WAN_STATUS_STOPPED, 0); + CcspTraceInfo(("%s %d - wan-status event set to stopped \n", __FUNCTION__, __LINE__)); + } + + return ret; +} + +/* WanManager_ClearDHCPData */ +/* This function must be used only with the mutex locked */ +static ANSC_STATUS WanManager_ClearDHCPData(DML_WAN_IFACE* pInterface) +{ + if(pInterface == NULL) + { + return ANSC_STATUS_FAILURE; + } + + memset(pInterface->IP.Path, 0, sizeof(pInterface->IP.Path)); + + /* DHCPv4 client */ + pInterface->IP.Ipv4Status = WAN_IFACE_IPV4_STATE_DOWN; + pInterface->IP.Ipv4Changed = FALSE; + memset(&(pInterface->IP.Ipv4Data), 0, sizeof(WANMGR_IPV4_DATA)); + pInterface->IP.Dhcp4cPid = 0; + if(pInterface->IP.pIpcIpv4Data != NULL) + { + free(pInterface->IP.pIpcIpv4Data); + pInterface->IP.pIpcIpv4Data = NULL; + } + + /* DHCPv6 client */ + pInterface->IP.Ipv6Status = WAN_IFACE_IPV6_STATE_DOWN; + pInterface->IP.Ipv6Changed = FALSE; + memset(&(pInterface->IP.Ipv6Data), 0, sizeof(WANMGR_IPV6_DATA)); + pInterface->IP.Dhcp6cPid = 0; + if(pInterface->IP.pIpcIpv6Data != NULL) + { + free(pInterface->IP.pIpcIpv6Data); + pInterface->IP.pIpcIpv6Data = NULL; + } + + return ANSC_STATUS_SUCCESS; +} + +/*********************************************************************************/ +/************************** TRANSITIONS ******************************************/ +/*********************************************************************************/ +static eWanState_t wan_transition_start(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl) +{ + if((pWanIfaceCtrl == NULL) || (pWanIfaceCtrl->pIfaceData == NULL)) + { + return ANSC_STATUS_FAILURE; + } + + DML_WAN_IFACE* pInterface = pWanIfaceCtrl->pIfaceData; + + pInterface->IP.Ipv4Status = WAN_IFACE_IPV4_STATE_DOWN; + pInterface->IP.Ipv6Status = WAN_IFACE_IPV6_STATE_DOWN; + pInterface->MAP.MaptStatus = WAN_IFACE_MAPT_STATE_DOWN; + pInterface->DSLite.Status = WAN_IFACE_DSLITE_STATE_DOWN; + + pInterface->Wan.Status = WAN_IFACE_STATUS_INITIALISING; + pInterface->Wan.LinkStatus = WAN_IFACE_LINKSTATUS_CONFIGURING; + + WanMgr_RdkBus_updateInterfaceUpstreamFlag(pInterface->Phy.Path, TRUE); + + if(pInterface->Wan.ActiveLink == TRUE) + { + const char if_dsl_name[] = "dsl"; + if (strncmp(pInterface->Name, if_dsl_name, strlen(if_dsl_name)) == 0) + { + WanMgr_UpdatePlatformStatus(WANMGR_LINK_UP); + } + else + { + WanMgr_UpdatePlatformStatus(WANMGR_CONNECTING); + } + } + + CcspTraceInfo(("%s %d - Interface '%s' - TRANSITION START\n", __FUNCTION__, __LINE__, pInterface->Name)); + + /* TODO: Need to handle crash recovery */ + return WAN_STATE_CONFIGURING_WAN; +} + +static eWanState_t wan_transition_physical_interface_down(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl) +{ + if((pWanIfaceCtrl == NULL) || (pWanIfaceCtrl->pIfaceData == NULL)) + { + return ANSC_STATUS_FAILURE; + } + + DML_WAN_IFACE* pInterface = pWanIfaceCtrl->pIfaceData; + + if(pInterface->PPP.Enable == FALSE) + { + /* Stops DHCPv4 client */ + WanManager_StopDhcpv4Client(TRUE); // release dhcp lease + + /* Stops DHCPv6 client */ + WanManager_StopDhcpv6Client(TRUE); // release dhcp lease + +#ifdef FEATURE_IPOE_HEALTH_CHECK + if (pWanIfaceCtrl->IhcPid > 0) + { + if (WanManager_StopIpoeHealthCheckService(pWanIfaceCtrl->IhcPid) == ANSC_STATUS_FAILURE) + { + CcspTraceError(("%s %d - Failed to kill IHC process interface %s \n", __FUNCTION__, __LINE__, pInterface->Wan.Name)); + } + pWanIfaceCtrl->IhcPid = 0; + } +#endif // FEATURE_IPOE_HEALTH_CHECK + } + else + { + /* Stops DHCPv6 client */ + WanManager_StopDhcpv6Client(TRUE); // release dhcp lease + + /* Delete PPP session */ + WanManager_DeletePPPSession(pInterface); + } + + WanMgr_RdkBus_updateInterfaceUpstreamFlag(pInterface->Phy.Path, FALSE); + + CcspTraceInfo(("%s %d - Interface '%s' - TRANSITION DECONFIGURING WAN\n", __FUNCTION__, __LINE__, pInterface->Name)); + + return WAN_STATE_DECONFIGURING_WAN; +} + +static eWanState_t wan_transition_wan_up(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl) +{ + if((pWanIfaceCtrl == NULL) || (pWanIfaceCtrl->pIfaceData == NULL)) + { + return ANSC_STATUS_FAILURE; + } + + DML_WAN_IFACE* pInterface = pWanIfaceCtrl->pIfaceData; + + + pInterface->Wan.Status = WAN_IFACE_STATUS_VALIDATING; + + + /* TODO: Runs WAN Validation processes based on the Wan.Validation flags, + e.g. if Wan.Validation.Discovery-Offer is set to TRUE, a threaded + process will be started to run the DHCPv4 Discovery-Offer validation. + The results of each validation process will be stored internally + to the state machine (i.e. not expressed in the data model */ + if(pInterface->Wan.ActiveLink == TRUE) + { + WanMgr_UpdatePlatformStatus(WANMGR_CONNECTING); + } + + CcspTraceInfo(("%s %d - Interface '%s' - TRANSITION VALIDATING WAN\n", __FUNCTION__, __LINE__, pInterface->Name)); + + return WAN_STATE_VALIDATING_WAN; +} + +static eWanState_t wan_transition_wan_validated(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl) +{ + if((pWanIfaceCtrl == NULL) || (pWanIfaceCtrl->pIfaceData == NULL)) + { + return ANSC_STATUS_FAILURE; + } + + DML_WAN_IFACE* pInterface = pWanIfaceCtrl->pIfaceData; + + + pInterface->Wan.Status = WAN_IFACE_STATUS_UP; + + /* Clear DHCP data */ + WanManager_ClearDHCPData(pInterface); + + if( pInterface->PPP.Enable == FALSE ) + { +#ifdef FEATURE_IPOE_HEALTH_CHECK + if (pInterface->Wan.ActiveLink == TRUE) + { + UINT IhcPid = 0; + IhcPid = WanManager_StartIpoeHealthCheckService(pInterface->Wan.Name); + if (IhcPid > 0) + { + pWanIfaceCtrl->IhcPid = IhcPid; + CcspTraceError(("%s %d - Starting IPoE Health Check pid - %u for interface %s \n", __FUNCTION__, __LINE__, pWanIfaceCtrl->IhcPid, pInterface->Wan.Name)); + } + else + { + CcspTraceError(("%s %d - Failed to start IPoE Health Check for interface %s \n", __FUNCTION__, __LINE__, pInterface->Wan.Name)); + } + } +#endif // FEATURE_IPOE_HEALTH_CHECK + /* Start DHCPv4 client */ + CcspTraceInfo(("%s %d - Staring udhcpc on interface %s \n", __FUNCTION__, __LINE__, pInterface->Wan.Name)); + uint32_t pid = WanManager_StartDhcpv4Client(pInterface->Wan.Name, FALSE); + + /* Start DHCPv6 Client */ + CcspTraceInfo(("%s %d - Staring dibbler-client on interface %s \n", __FUNCTION__, __LINE__, pInterface->Wan.Name)); + if (RETURN_OK != WanManager_StartDhcpv6Client(pInterface->Wan.Name, FALSE)) + { + CcspTraceError(("%s %d - Failed to start DHCPv6 client on %s \n", __FUNCTION__, __LINE__, pInterface->Wan.Name)); + } + CcspTraceInfo(("%s %d - Started dibbler-client on interface %s \n", __FUNCTION__, __LINE__, pInterface->Wan.Name)); + } + else + { + WanManager_CreatePPPSession(pInterface); + } + + CcspTraceInfo(("%s %d - Interface '%s' - TRANSITION OBTAINING IP ADDRESSES\n", __FUNCTION__, __LINE__, pInterface->Name)); + + return WAN_STATE_OBTAINING_IP_ADDRESSES; +} + +static eWanState_t wan_transition_refreshing_wan(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl) +{ + if((pWanIfaceCtrl == NULL) || (pWanIfaceCtrl->pIfaceData == NULL)) + { + return ANSC_STATUS_FAILURE; + } + + DML_WAN_IFACE* pInterface = pWanIfaceCtrl->pIfaceData; + + if(pInterface->PPP.Enable == FALSE) + { + /* Stops DHCPv4 client */ + WanManager_StopDhcpv4Client(TRUE); // release dhcp lease + + /* Stops DHCPv6 client */ + WanManager_StopDhcpv6Client(TRUE); // release dhcp lease + } + else + { + /* Stops DHCPv6 client */ + WanManager_StopDhcpv6Client(TRUE); // release dhcp lease + + /* Delete PPP session */ + WanManager_DeletePPPSession(pInterface); + } + + /* Sets Ethernet.Link.{i}.X_RDK_Refresh to TRUE in VLAN & Bridging Manager + in order to refresh the WAN link */ + if(WanMgr_Send_InterfaceRefresh(pInterface) != ANSC_STATUS_SUCCESS) + { + CcspTraceError(("%s %d - Interface '%s' - Sending Refresh message failed\n", __FUNCTION__, __LINE__, pInterface->Name)); + } + + pInterface->Wan.LinkStatus = WAN_IFACE_LINKSTATUS_CONFIGURING; + pInterface->Wan.Refresh = FALSE; + + CcspTraceInfo(("%s %d - Interface '%s' - TRANSITION REFRESHING WAN\n", __FUNCTION__, __LINE__, pInterface->Name)); + + return WAN_STATE_REFRESHING_WAN; +} + +static eWanState_t wan_transition_wan_refreshed(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl) +{ + if((pWanIfaceCtrl == NULL) || (pWanIfaceCtrl->pIfaceData == NULL)) + { + return ANSC_STATUS_FAILURE; + } + + DML_WAN_IFACE* pInterface = pWanIfaceCtrl->pIfaceData; + + /* Clear DHCP data */ + WanManager_ClearDHCPData(pInterface); + + if( pInterface->PPP.Enable == FALSE ) + { + /* Start dhcp clients */ + /* DHCPv4 client */ + CcspTraceInfo(("%s %d - Staring dhcpc on interface %s \n", __FUNCTION__, __LINE__, pInterface->Wan.Name)); + uint32_t pid = WanManager_StartDhcpv4Client(pInterface->Wan.Name, FALSE); + CcspTraceInfo(("%s %d - Started dhcpc on interface %s, pid %d \n", __FUNCTION__, __LINE__, pInterface->Wan.Name, pid)); + + /* DHCPv6 Client */ + if (RETURN_OK != WanManager_StartDhcpv6Client(pInterface->Wan.Name, FALSE)) + { + CcspTraceError(("%s %d - Failed to start DHCPv6 client on %s \n", __FUNCTION__, __LINE__, pInterface->Wan.Name )); + } + } + else + { + WanManager_CreatePPPSession(pInterface); + } + + CcspTraceInfo(("%s %d - Interface '%s' - TRANSITION OBTAINING IP ADDRESSES\n", __FUNCTION__, __LINE__, pInterface->Name)); + + return WAN_STATE_OBTAINING_IP_ADDRESSES; +} + +static eWanState_t wan_transition_ipv4_up(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl) +{ + ANSC_STATUS ret; + char buf[BUFLEN_128] = {0}; + + if((pWanIfaceCtrl == NULL) || (pWanIfaceCtrl->pIfaceData == NULL)) + { + return ANSC_STATUS_FAILURE; + } + + DML_WAN_IFACE* pInterface = pWanIfaceCtrl->pIfaceData; + + if(pInterface->Wan.ActiveLink == TRUE ) + { + /* Configure IPv4. */ + ret = wan_setUpIPv4(pInterface); + if (ret != RETURN_OK) + { + CcspTraceError(("%s %d - Failed to configure IPv4 successfully \n", __FUNCTION__, __LINE__)); + } + +#ifdef FEATURE_IPOE_HEALTH_CHECK + if ((pInterface->PPP.Enable == FALSE) && (pWanIfaceCtrl->IhcPid > 0)) + { + WanMgr_SendMsgToIHC(IPOE_MSG_WAN_CONNECTION_UP, pInterface->Wan.Name); + } +#endif + } + + /* Force reset ipv4 state global flag. */ + pInterface->IP.Ipv4Changed = FALSE; + + + pInterface->IP.Ipv4Status = WAN_IFACE_IPV4_STATE_UP; + + sysevent_get(sysevent_fd, sysevent_token, SYSEVENT_WAN_SERVICE_STATUS, buf, sizeof(buf)); + if (strcmp(buf, WAN_STATUS_STARTED)) + { + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_WAN_SERVICE_STATUS, WAN_STATUS_STARTED, 0); + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_FIREWALL_RESTART, NULL, 0); + } + + memset(buf, 0, BUFLEN_128); + sysevent_get(sysevent_fd, sysevent_token, SYSEVENT_IPV6_CONNECTION_STATE, buf, sizeof(buf)); + + if(pInterface->IP.Ipv6Status == WAN_IFACE_IPV6_STATE_UP && !strcmp(buf, WAN_STATUS_UP)) + { + if(pInterface->Wan.ActiveLink == TRUE) + { + WanMgr_UpdatePlatformStatus(WANMGR_CONNECTED); + } + + CcspTraceInfo(("%s %d - Interface '%s' - TRANSITION DUAL STACK ACTIVE\n", __FUNCTION__, __LINE__, pInterface->Name)); + return WAN_STATE_DUAL_STACK_ACTIVE; + } + + if(pInterface->Wan.ActiveLink == TRUE) + { + WanMgr_UpdatePlatformStatus(WANMGR_LINK_V4UP_V6DOWN); + } + + CcspTraceInfo(("%s %d - Interface '%s' - TRANSITION IPV4 LEASED\n", __FUNCTION__, __LINE__, pInterface->Name)); + + return WAN_STATE_IPV4_LEASED; +} + +static eWanState_t wan_transition_ipv4_down(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl) +{ + char buf[BUFLEN_128] = {0}; + + if((pWanIfaceCtrl == NULL) || (pWanIfaceCtrl->pIfaceData == NULL)) + { + return ANSC_STATUS_FAILURE; + } + + DML_WAN_IFACE* pInterface = pWanIfaceCtrl->pIfaceData; + + if (wan_tearDownIPv4(pInterface) != RETURN_OK) + { + CcspTraceError(("%s %d - Failed to tear down IPv4 for %s \n", __FUNCTION__, __LINE__, pInterface->Wan.Name)); + } + + WanManager_UpdateInterfaceStatus(pInterface, WANMGR_IFACE_CONNECTION_DOWN); +#ifdef FEATURE_IPOE_HEALTH_CHECK + if((pInterface->Wan.ActiveLink == TRUE) && (pInterface->PPP.Enable == FALSE) && (pWanIfaceCtrl->IhcPid > 0)) + { + WanMgr_SendMsgToIHC(IPOE_MSG_WAN_CONNECTION_DOWN, pInterface->Wan.Name); + } +#endif + + sysevent_get(sysevent_fd, sysevent_token, SYSEVENT_IPV6_CONNECTION_STATE, buf, sizeof(buf)); + + if(pInterface->IP.Ipv6Status == WAN_IFACE_IPV6_STATE_UP && !strcmp(buf, WAN_STATUS_UP)) + { + if(pInterface->Wan.ActiveLink == TRUE) + { + WanMgr_UpdatePlatformStatus(WANMGR_LINK_V6UP_V4DOWN); + } + + CcspTraceInfo(("%s %d - Interface '%s' - TRANSITION IPV6 LEASED\n", __FUNCTION__, __LINE__, pInterface->Name)); + return WAN_STATE_IPV6_LEASED; + } + + if(pInterface->Wan.ActiveLink == TRUE) + { + WanMgr_UpdatePlatformStatus(WANMGR_CONNECTING); + } + + CcspTraceInfo(("%s %d - Interface '%s' - TRANSITION OBTAINING IP ADDRESSES\n", __FUNCTION__, __LINE__, pInterface->Name)); + return WAN_STATE_OBTAINING_IP_ADDRESSES; +} + +static eWanState_t wan_transition_ipv6_up(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl) +{ + ANSC_STATUS ret; + char buf[BUFLEN_128] = {0}; + + if((pWanIfaceCtrl == NULL) || (pWanIfaceCtrl->pIfaceData == NULL)) + { + return ANSC_STATUS_FAILURE; + } + + DML_WAN_IFACE* pInterface = pWanIfaceCtrl->pIfaceData; + + if(pInterface->Wan.ActiveLink == TRUE ) + { + /* Configure IPv6. */ + ret = wan_setUpIPv6(pInterface); + if (ret != RETURN_OK) + { + CcspTraceError(("%s %d - Failed to configure IPv6 successfully \n", __FUNCTION__, __LINE__)); + } +#ifdef FEATURE_IPOE_HEALTH_CHECK + if ((pInterface->PPP.Enable == FALSE) && (pWanIfaceCtrl->IhcPid > 0)) + { + WanMgr_SendMsgToIHC(IPOE_MSG_WAN_CONNECTION_IPV6_UP, pInterface->Wan.Name); + } +#endif + } + + pInterface->IP.Ipv6Changed = FALSE; + pInterface->IP.Ipv6Status = WAN_IFACE_IPV6_STATE_UP; + + sysevent_get(sysevent_fd, sysevent_token, SYSEVENT_WAN_SERVICE_STATUS, buf, sizeof(buf)); + if (strcmp(buf, WAN_STATUS_STARTED)) + { + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_WAN_SERVICE_STATUS, WAN_STATUS_STARTED, 0); + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_FIREWALL_RESTART, NULL, 0); + } + + memset(buf, 0, BUFLEN_128); + sysevent_get(sysevent_fd, sysevent_token, SYSEVENT_IPV4_CONNECTION_STATE, buf, sizeof(buf)); + + if( pInterface->IP.Ipv4Status == WAN_IFACE_IPV4_STATE_UP && !strcmp(buf, WAN_STATUS_UP)) + { + if(pInterface->Wan.ActiveLink == TRUE) + { + WanMgr_UpdatePlatformStatus(WANMGR_CONNECTED); + } + + CcspTraceInfo(("%s %d - Interface '%s' - TRANSITION DUAL STACK ACTIVE\n", __FUNCTION__, __LINE__, pInterface->Name)); + return WAN_STATE_DUAL_STACK_ACTIVE; + } + + if(pInterface->Wan.ActiveLink == TRUE) + { + WanMgr_UpdatePlatformStatus(WANMGR_LINK_V6UP_V4DOWN); + } + + CcspTraceInfo(("%s %d - Interface '%s' - TRANSITION IPV6 LEASED\n", __FUNCTION__, __LINE__, pInterface->Name)); + return WAN_STATE_IPV6_LEASED; +} + +static eWanState_t wan_transition_ipv6_down(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl) +{ + char buf[BUFLEN_128] = {0}; + + if((pWanIfaceCtrl == NULL) || (pWanIfaceCtrl->pIfaceData == NULL)) + { + return ANSC_STATUS_FAILURE; + } + + DML_WAN_IFACE* pInterface = pWanIfaceCtrl->pIfaceData; + + if (wan_tearDownIPv6(pInterface) != RETURN_OK) + { + CcspTraceError(("%s %d - Failed to tear down IPv6 for %s \n", __FUNCTION__, __LINE__, pInterface->Wan.Name)); + } + + WanManager_UpdateInterfaceStatus(pInterface, WANMGR_IFACE_CONNECTION_IPV6_DOWN); + +#ifdef FEATURE_IPOE_HEALTH_CHECK + if ((pInterface->Wan.ActiveLink == TRUE) && (pInterface->PPP.Enable == FALSE) && (pWanIfaceCtrl->IhcPid > 0)) + { + WanMgr_SendMsgToIHC(IPOE_MSG_WAN_CONNECTION_IPV6_DOWN, pInterface->Wan.Name); + } +#endif + + sysevent_get(sysevent_fd, sysevent_token, SYSEVENT_IPV4_CONNECTION_STATE, buf, sizeof(buf)); + + if(pInterface->IP.Ipv4Status == WAN_IFACE_IPV4_STATE_UP && !strcmp(buf, WAN_STATUS_UP)) + { + if(pInterface->Wan.ActiveLink == TRUE) + { + WanMgr_UpdatePlatformStatus(WANMGR_LINK_V4UP_V6DOWN); + } + + CcspTraceInfo(("%s %d - Interface '%s' - TRANSITION IPV4 LEASED\n", __FUNCTION__, __LINE__, pInterface->Name)); + return WAN_STATE_IPV4_LEASED; + } + + if(pInterface->Wan.ActiveLink == TRUE) + { + WanMgr_UpdatePlatformStatus(WANMGR_CONNECTING); + } + + CcspTraceInfo(("%s %d - Interface '%s' - TRANSITION OBTAINING IP ADDRESSES\n", __FUNCTION__, __LINE__, pInterface->Name)); + return WAN_STATE_OBTAINING_IP_ADDRESSES; + +} + +static eWanState_t wan_transition_dual_stack_down(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl) +{ + CcspTraceInfo(("%s %d - Enter \n", __FUNCTION__, __LINE__)); + wan_transition_ipv4_down(pWanIfaceCtrl); + wan_transition_ipv6_down(pWanIfaceCtrl); + + CcspTraceInfo(("%s %d - TRANSITION OBTAINING IP ADDRESSES\n", __FUNCTION__, __LINE__)); + return WAN_STATE_OBTAINING_IP_ADDRESSES; +} + +static eWanState_t wan_transition_ipv4_over_ipv6_up(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl) +{ + CcspTraceInfo(("%s %d - Enter \n", __FUNCTION__, __LINE__)); + /* TODO: Handle DSLite and MAP-T UP cases */ + + CcspTraceInfo(("%s %d - TRANSITION IPV4 LEASED\n", __FUNCTION__, __LINE__)); + return WAN_STATE_IPV4_LEASED; +} + +static eWanState_t wan_transition_ipv4_over_ipv6_down(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl) +{ + CcspTraceInfo(("%s %d - Enter \n", __FUNCTION__, __LINE__)); + /* TODO: Handle DSLite and MAP-T DOWN cases */ + + CcspTraceInfo(("%s %d - TRANSITION IPV4 LEASED\n", __FUNCTION__, __LINE__)); + return WAN_STATE_IPV4_LEASED; +} + +static eWanState_t wan_transition_exit(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl) +{ + if((pWanIfaceCtrl == NULL) || (pWanIfaceCtrl->pIfaceData == NULL)) + { + return ANSC_STATUS_FAILURE; + } + + DML_WAN_IFACE* pInterface = pWanIfaceCtrl->pIfaceData; + + pInterface->Wan.Status = WAN_IFACE_STATUS_DISABLED; + pInterface->Wan.Refresh = FALSE; + pInterface->Wan.ActiveLink = FALSE; + + WanMgr_UpdatePlatformStatus(WANMGR_DISCONNECTED); + + CcspTraceInfo(("%s %d - Interface '%s' - EXITING STATE MACHINE\n", __FUNCTION__, __LINE__, pInterface->Name)); + return WAN_STATE_EXIT; +} + + +/*********************************************************************************/ +/**************************** STATES *********************************************/ +/*********************************************************************************/ +static eWanState_t wan_state_configuring_wan(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl) +{ + if((pWanIfaceCtrl == NULL) || (pWanIfaceCtrl->pIfaceData == NULL)) + { + return ANSC_STATUS_FAILURE; + } + + DML_WAN_IFACE* pInterface = pWanIfaceCtrl->pIfaceData; + + if (pWanIfaceCtrl->WanEnable == FALSE || + pInterface->Wan.ActiveLink == FALSE || + pInterface->Phy.Status == WAN_IFACE_PHY_STATUS_DOWN || + pInterface->Wan.LinkStatus == WAN_IFACE_LINKSTATUS_DOWN ) + { + return wan_transition_physical_interface_down(pWanIfaceCtrl); + } + + if (pInterface->Wan.LinkStatus == WAN_IFACE_LINKSTATUS_UP ) + { + return wan_transition_wan_up(pWanIfaceCtrl); + } + + return WAN_STATE_CONFIGURING_WAN; +} + +static eWanState_t wan_state_validating_wan(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl) +{ + if((pWanIfaceCtrl == NULL) || (pWanIfaceCtrl->pIfaceData == NULL)) + { + return ANSC_STATUS_FAILURE; + } + + DML_WAN_IFACE* pInterface = pWanIfaceCtrl->pIfaceData; + + if (pWanIfaceCtrl->WanEnable == FALSE || + pInterface->Wan.ActiveLink == FALSE || + pInterface->Phy.Status == WAN_IFACE_PHY_STATUS_DOWN || + pInterface->Wan.LinkStatus == WAN_IFACE_LINKSTATUS_DOWN ) + { + return wan_transition_physical_interface_down(pWanIfaceCtrl); + } + + if (pInterface->Wan.LinkStatus == WAN_IFACE_LINKSTATUS_CONFIGURING ) + { + /* TODO: We'll need to call a transition that stops any running validation + processes before returning to the CONFIGURING WAN state */ + return WAN_STATE_CONFIGURING_WAN; + } + + /* TODO: Waits for every running validation process to complete, then checks the results */ + + return wan_transition_wan_validated(pWanIfaceCtrl); +} + +static eWanState_t wan_state_obtaining_ip_addresses(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl) +{ + if((pWanIfaceCtrl == NULL) || (pWanIfaceCtrl->pIfaceData == NULL)) + { + return ANSC_STATUS_FAILURE; + } + + DML_WAN_IFACE* pInterface = pWanIfaceCtrl->pIfaceData; + + if (pWanIfaceCtrl->WanEnable == FALSE || + pInterface->Wan.ActiveLink == FALSE || + pInterface->Phy.Status == WAN_IFACE_PHY_STATUS_DOWN || + pInterface->Wan.LinkStatus == WAN_IFACE_LINKSTATUS_DOWN ) + { + return wan_transition_physical_interface_down(pWanIfaceCtrl); + } + + if ( pInterface->Wan.LinkStatus == WAN_IFACE_LINKSTATUS_CONFIGURING || + pInterface->Wan.Refresh == TRUE) + { + return wan_state_refreshing_wan(pWanIfaceCtrl); + } + + if (pInterface->IP.Ipv4Status == WAN_IFACE_IPV4_STATE_UP) + { + return wan_transition_ipv4_up(pWanIfaceCtrl); + } + else if (pInterface->IP.Ipv6Status == WAN_IFACE_IPV6_STATE_UP) + { + if(pInterface->IP.Ipv6Changed == TRUE) + { + /* Set sysevents to trigger P&M */ + if (setUpLanPrefixIPv6(pInterface) != RETURN_OK) + { + CcspTraceError((" %s %d - Failed to configure IPv6 prefix \n", __FUNCTION__, __LINE__)); + } + /* Reset isIPv6ConfigChanged */ + pInterface->IP.Ipv6Changed = FALSE; + return WAN_STATE_OBTAINING_IP_ADDRESSES; + } + if (checkIpv6AddressAssignedToBridge() == RETURN_OK) + { + return wan_transition_ipv6_up(pWanIfaceCtrl); + } + } + + return WAN_STATE_OBTAINING_IP_ADDRESSES; +} + +static eWanState_t wan_state_ipv4_leased(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl) +{ + if((pWanIfaceCtrl == NULL) || (pWanIfaceCtrl->pIfaceData == NULL)) + { + return ANSC_STATUS_FAILURE; + } + + DML_WAN_IFACE* pInterface = pWanIfaceCtrl->pIfaceData; + + if (pWanIfaceCtrl->WanEnable == FALSE || + pInterface->Wan.ActiveLink == FALSE || + pInterface->Phy.Status == WAN_IFACE_PHY_STATUS_DOWN || + pInterface->Wan.LinkStatus == WAN_IFACE_LINKSTATUS_DOWN || + pInterface->IP.Ipv4Status == WAN_IFACE_IPV4_STATE_DOWN || + pInterface->IP.Ipv4Changed == TRUE) + { + return wan_transition_ipv4_down(pWanIfaceCtrl); + } + else if (pInterface->IP.Ipv6Status == WAN_IFACE_IPV6_STATE_UP) + { + if(pInterface->IP.Ipv6Changed == TRUE) + { + /* Set sysevents to trigger P&M */ + if (setUpLanPrefixIPv6(pInterface) != RETURN_OK) + { + CcspTraceError((" %s %d - Failed to configure IPv6 prefix \n", __FUNCTION__, __LINE__)); + } + /* Reset isIPv6ConfigChanged */ + pInterface->IP.Ipv6Changed = FALSE; + return WAN_STATE_IPV4_LEASED; + } + if (checkIpv6AddressAssignedToBridge() == RETURN_OK) + { + return wan_transition_ipv6_up(pWanIfaceCtrl); + } + } + + return WAN_STATE_IPV4_LEASED; +} + +static eWanState_t wan_state_ipv6_leased(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl) +{ + if((pWanIfaceCtrl == NULL) || (pWanIfaceCtrl->pIfaceData == NULL)) + { + return ANSC_STATUS_FAILURE; + } + + DML_WAN_IFACE* pInterface = pWanIfaceCtrl->pIfaceData; + + if (pWanIfaceCtrl->WanEnable == FALSE || + pInterface->Wan.ActiveLink == FALSE || + pInterface->Phy.Status == WAN_IFACE_PHY_STATUS_DOWN || + pInterface->Wan.LinkStatus == WAN_IFACE_LINKSTATUS_DOWN || + pInterface->IP.Ipv6Status == WAN_IFACE_IPV6_STATE_DOWN || + pInterface->IP.Ipv6Changed == TRUE) + { + return wan_transition_ipv6_down(pWanIfaceCtrl); + } + else if (pInterface->IP.Ipv4Status == WAN_IFACE_IPV4_STATE_UP) + { + return wan_transition_ipv4_up(pWanIfaceCtrl); + } + else if (pInterface->Wan.EnableDSLite == TRUE && + pInterface->Wan.ActiveLink == TRUE && + pInterface->DSLite.Status == WAN_IFACE_DSLITE_STATE_UP) + { + return wan_transition_ipv4_over_ipv6_up(pWanIfaceCtrl); + } + else if (pInterface->Wan.EnableMAPT == TRUE && + pInterface->Wan.ActiveLink == TRUE && + pInterface->MAP.MaptStatus == WAN_IFACE_MAPT_STATE_UP) + { + return wan_transition_ipv4_over_ipv6_up(pWanIfaceCtrl); + } + + return WAN_STATE_IPV6_LEASED; +} + +static eWanState_t wan_state_dual_stack_active(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl) +{ + if((pWanIfaceCtrl == NULL) || (pWanIfaceCtrl->pIfaceData == NULL)) + { + return ANSC_STATUS_FAILURE; + } + + DML_WAN_IFACE* pInterface = pWanIfaceCtrl->pIfaceData; + + if (pWanIfaceCtrl->WanEnable == FALSE || + pInterface->Wan.ActiveLink == FALSE || + pInterface->Phy.Status == WAN_IFACE_PHY_STATUS_DOWN || + pInterface->Wan.LinkStatus == WAN_IFACE_LINKSTATUS_DOWN) + { + return wan_transition_dual_stack_down(pWanIfaceCtrl); + } + else if (pInterface->IP.Ipv4Status == WAN_IFACE_IPV4_STATE_DOWN ) + { + /* TODO: Add IPoE Health Check failed for IPv4 here */ + return wan_transition_ipv4_down(pWanIfaceCtrl); + } + else if (pInterface->IP.Ipv6Status == WAN_IFACE_IPV6_STATE_DOWN ) + { + /* TODO: Add IPoE Health Check failed for IPv6 here */ + return wan_transition_ipv6_down(pWanIfaceCtrl); + } + else if (pInterface->Wan.EnableDSLite == TRUE && + pInterface->Wan.ActiveLink == TRUE && + pInterface->DSLite.Status == WAN_IFACE_DSLITE_STATE_UP) + { + return wan_transition_ipv4_over_ipv6_up(pWanIfaceCtrl); + } + else if (pInterface->Wan.EnableMAPT == TRUE && + pInterface->Wan.ActiveLink == TRUE && + pInterface->MAP.MaptStatus == WAN_IFACE_MAPT_STATE_UP) + { + return wan_transition_ipv4_over_ipv6_up(pWanIfaceCtrl); + } + + return WAN_STATE_DUAL_STACK_ACTIVE; +} +static eWanState_t wan_state_ipv4_over_ipv6_active(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl) +{ + if((pWanIfaceCtrl == NULL) || (pWanIfaceCtrl->pIfaceData == NULL)) + { + return ANSC_STATUS_FAILURE; + } + + DML_WAN_IFACE* pInterface = pWanIfaceCtrl->pIfaceData; + + if (pWanIfaceCtrl->WanEnable == FALSE || + pInterface->Wan.ActiveLink == FALSE || + pInterface->Phy.Status == WAN_IFACE_PHY_STATUS_DOWN || + pInterface->Wan.LinkStatus == WAN_IFACE_LINKSTATUS_DOWN || + pInterface->IP.Ipv6Status == WAN_IFACE_IPV6_STATE_DOWN || + pInterface->IP.Ipv6Changed == TRUE) + { + return wan_transition_ipv4_over_ipv6_down(pWanIfaceCtrl); + } + else if (pInterface->Wan.EnableDSLite == FALSE || + pInterface->DSLite.Status == WAN_IFACE_DSLITE_STATE_DOWN || + pInterface->DSLite.Changed == TRUE ) + { + return wan_transition_ipv4_over_ipv6_down(pWanIfaceCtrl); + } + else if (pInterface->Wan.EnableMAPT == FALSE || + pInterface->MAP.MaptStatus == WAN_IFACE_MAPT_STATE_DOWN || + pInterface->MAP.MaptChanged == TRUE ) + { + return wan_transition_ipv4_over_ipv6_down(pWanIfaceCtrl); + } + + return WAN_STATE_IPV4_OVER_IPV6_ACTIVE; +} + +static eWanState_t wan_state_refreshing_wan(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl) +{ + if((pWanIfaceCtrl == NULL) || (pWanIfaceCtrl->pIfaceData == NULL)) + { + return ANSC_STATUS_FAILURE; + } + + DML_WAN_IFACE* pInterface = pWanIfaceCtrl->pIfaceData; + + if (pWanIfaceCtrl->WanEnable == FALSE || + pInterface->Wan.ActiveLink == FALSE || + pInterface->Phy.Status == WAN_IFACE_PHY_STATUS_DOWN || + pInterface->Wan.LinkStatus == WAN_IFACE_LINKSTATUS_DOWN) + { + return wan_transition_physical_interface_down(pWanIfaceCtrl); + } + + else if (pInterface->Wan.LinkStatus == WAN_IFACE_LINKSTATUS_UP && + pInterface->Wan.Refresh == TRUE) + { + return wan_transition_refreshing_wan(pWanIfaceCtrl); + } + else if (pInterface->Wan.LinkStatus == WAN_IFACE_LINKSTATUS_UP && + pInterface->Wan.Refresh == FALSE) + { + return wan_transition_wan_refreshed(pWanIfaceCtrl); + } + + return WAN_STATE_REFRESHING_WAN; +} + +static eWanState_t wan_state_deconfiguring_wan(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl) +{ + if((pWanIfaceCtrl == NULL) || (pWanIfaceCtrl->pIfaceData == NULL)) + { + return ANSC_STATUS_FAILURE; + } + + DML_WAN_IFACE* pInterface = pWanIfaceCtrl->pIfaceData; + + if (pInterface->Wan.LinkStatus == WAN_IFACE_LINKSTATUS_DOWN ) + { + return wan_transition_exit(pWanIfaceCtrl); + } + + return WAN_STATE_DECONFIGURING_WAN; +} + +static eWanState_t wan_state_exit(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl) +{ + if((pWanIfaceCtrl == NULL) || (pWanIfaceCtrl->pIfaceData == NULL)) + { + return ANSC_STATUS_FAILURE; + } + + //Clear WAN Name + memset(pWanIfaceCtrl->pIfaceData->Wan.Name, 0, sizeof(pWanIfaceCtrl->pIfaceData->Wan.Name)); + + /* Clear DHCP data */ + WanManager_ClearDHCPData(pWanIfaceCtrl->pIfaceData); + + + return WAN_STATE_EXIT; +} + +/*********************************************************************************/ +/*********************************************************************************/ +/*********************************************************************************/ +ANSC_STATUS WanMgr_InterfaceSMThread_Init(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl) +{ + int retStatus = ANSC_STATUS_SUCCESS; + return retStatus; +} + + +ANSC_STATUS WanMgr_InterfaceSMThread_Finalise(void) +{ + int retStatus = ANSC_STATUS_SUCCESS; + + retStatus = WanMgr_CloseIpcServer(); + if(retStatus != ANSC_STATUS_SUCCESS) + { + CcspTraceInfo(("%s %d - IPC Thread failed to start!\n", __FUNCTION__, __LINE__ )); + } + + return retStatus; +} + + +static ANSC_STATUS WanMgr_IfaceIpcMsg_handle(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl) +{ + if((pWanIfaceCtrl == NULL) || (pWanIfaceCtrl->pIfaceData == NULL)) + { + return ANSC_STATUS_FAILURE; + } + + DML_WAN_IFACE* pInterface = pWanIfaceCtrl->pIfaceData; + + if (pInterface->IP.pIpcIpv4Data != NULL ) + { + wanmgr_handle_dchpv4_event_data(pInterface); + } + + if (pInterface->IP.pIpcIpv6Data != NULL ) + { + wanmgr_handle_dchpv6_event_data(pInterface); + } + + return ANSC_STATUS_SUCCESS; +} + + +static void* WanMgr_InterfaceSMThread( void *arg ) +{ + CcspTraceInfo(("%s %d \n", __FUNCTION__, __LINE__)); + + //Validate buffer + if ( NULL == arg ) + { + CcspTraceError(("%s %d Invalid buffer\n", __FUNCTION__,__LINE__)); + //Cleanup current thread when exit + pthread_exit(NULL); + } + + //SM variables + WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl = ( WanMgr_IfaceSM_Controller_t *) arg; + WanMgr_Iface_Data_t* pWanDmlIfaceData = NULL; + eWanState_t iface_sm_state = WAN_STATE_EXIT; + bool bRunning = true; + + // event handler + int n = 0; + struct timeval tv; + + + //detach thread from caller stack + pthread_detach(pthread_self()); + + + CcspTraceInfo(("%s %d - Interface state machine (TID %lu) initialising for iface idx %d\n", __FUNCTION__, __LINE__, pthread_self(), pWanIfaceCtrl->interfaceIdx)); + + + // initialise state machine + if(WanMgr_InterfaceSMThread_Init(pWanIfaceCtrl) != ANSC_STATUS_SUCCESS) + { + CcspTraceError(("%s %d Policy Controller Error \n", __FUNCTION__, __LINE__)); + return ANSC_STATUS_FAILURE; + } + + //Transition Start + pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pWanIfaceCtrl->interfaceIdx); + if(pWanDmlIfaceData != NULL) + { + pWanIfaceCtrl->pIfaceData = &(pWanDmlIfaceData->data); + iface_sm_state = wan_transition_start(pWanIfaceCtrl); // do this first before anything else to init variables + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + else + { + bRunning = false; + } + + while (bRunning) + { + pWanIfaceCtrl->pIfaceData = NULL; + + /* Wait up to 500 milliseconds */ + tv.tv_sec = 0; + tv.tv_usec = LOOP_TIMEOUT; + + n = select(0, NULL, NULL, NULL, &tv); + if (n < 0) + { + /* interrupted by signal or something, continue */ + continue; + } + + + //Update Wan config + WanMgr_Config_Data_t* pWanConfigData = WanMgr_GetConfigData_locked(); + if(pWanConfigData != NULL) + { + pWanIfaceCtrl->WanEnable = pWanConfigData->data.Enable; + + WanMgrDml_GetConfigData_release(pWanConfigData); + } + + //Get Interface data + pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pWanIfaceCtrl->interfaceIdx); + if(pWanDmlIfaceData != NULL) + { + pWanIfaceCtrl->pIfaceData = &(pWanDmlIfaceData->data); + } + + //Handle IPC messages + WanMgr_IfaceIpcMsg_handle(pWanIfaceCtrl); + + // process state + switch (iface_sm_state) + { + case WAN_STATE_CONFIGURING_WAN: + { + iface_sm_state = wan_state_configuring_wan(pWanIfaceCtrl); + break; + } + case WAN_STATE_VALIDATING_WAN: + { + iface_sm_state = wan_state_validating_wan(pWanIfaceCtrl); + break; + } + case WAN_STATE_OBTAINING_IP_ADDRESSES: + { + iface_sm_state = wan_state_obtaining_ip_addresses(pWanIfaceCtrl); + break; + } + case WAN_STATE_IPV4_LEASED: + { + iface_sm_state = wan_state_ipv4_leased(pWanIfaceCtrl); + break; + } + case WAN_STATE_IPV6_LEASED: + { + iface_sm_state = wan_state_ipv6_leased(pWanIfaceCtrl); + break; + } + case WAN_STATE_DUAL_STACK_ACTIVE: + { + iface_sm_state = wan_state_dual_stack_active(pWanIfaceCtrl); + break; + } + case WAN_STATE_IPV4_OVER_IPV6_ACTIVE: + { + iface_sm_state = wan_state_ipv4_over_ipv6_active(pWanIfaceCtrl); + break; + } + case WAN_STATE_REFRESHING_WAN: + { + iface_sm_state = wan_state_refreshing_wan(pWanIfaceCtrl); + break; + } + case WAN_STATE_DECONFIGURING_WAN: + { + iface_sm_state = wan_state_deconfiguring_wan(pWanIfaceCtrl); + break; + } + case WAN_STATE_EXIT : + default: + { + iface_sm_state = wan_state_exit(pWanIfaceCtrl); + bRunning = false; + CcspTraceInfo(("%s %d - Exit from state machine\n", __FUNCTION__, __LINE__)); + break; + } + } + + if(pWanDmlIfaceData != NULL) + { + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + + } + + WanMgr_InterfaceSMThread_Finalise(); + + + CcspTraceInfo(("%s %d - Interface state machine (TID %lu) exiting for iface idx %d\n", __FUNCTION__, __LINE__, pthread_self(), pWanIfaceCtrl->interfaceIdx)); + + //Free current private resource before exit + if(NULL != pWanIfaceCtrl) + { + free(pWanIfaceCtrl); + pWanIfaceCtrl = NULL; + } + + pthread_exit(NULL); +} + + +int WanMgr_StartInterfaceStateMachine(WanMgr_IfaceSM_Controller_t *wanIf) +{ + WanMgr_IfaceSM_Controller_t * wanIfLocal = NULL; + pthread_t wanSmThreadId; + int iErrorCode = 0; + static int siKeyCreated = 0; + + //Allocate memory and pass it to thread + wanIfLocal = ( WanMgr_IfaceSM_Controller_t * )malloc( sizeof( WanMgr_IfaceSM_Controller_t ) ); + if( NULL == wanIfLocal ) + { + CcspTraceError(("%s %d Failed to allocate memory\n", __FUNCTION__, __LINE__)); + return -1; + } + + //Copy buffer + memcpy( wanIfLocal , wanIf, sizeof(WanMgr_IfaceSM_Controller_t) ); + + CcspTraceInfo (("%s %d - WAN interface data received in the state machine (iface idx %d) \n", __FUNCTION__, __LINE__, wanIfLocal->interfaceIdx)); + + //Wanmanager state machine thread + iErrorCode = pthread_create( &wanSmThreadId, NULL, &WanMgr_InterfaceSMThread, (void*)wanIfLocal ); + + if( 0 != iErrorCode ) + { + CcspTraceInfo(("%s %d - Failed to start WanManager State Machine Thread EC:%d\n", __FUNCTION__, __LINE__, iErrorCode )); + } + else + { + CcspTraceInfo(("%s %d - WanManager State Machine Thread Started Successfully\n", __FUNCTION__, __LINE__ )); + } + return iErrorCode ; +} + + +void WanMgr_IfaceSM_Init(WanMgr_IfaceSM_Controller_t* pWanIfaceSMCtrl, INT iface_idx) +{ + if(pWanIfaceSMCtrl != NULL) + { + pWanIfaceSMCtrl->WanEnable = FALSE; + pWanIfaceSMCtrl->interfaceIdx = iface_idx; +#ifdef FEATURE_IPOE_HEALTH_CHECK + pWanIfaceSMCtrl->IhcPid = 0; +#endif + pWanIfaceSMCtrl->pIfaceData = NULL; + } +} diff --git a/source/WanManager/wanmgr_interface_sm.h b/source/WanManager/wanmgr_interface_sm.h new file mode 100644 index 00000000..ad589544 --- /dev/null +++ b/source/WanManager/wanmgr_interface_sm.h @@ -0,0 +1,75 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2015 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +#ifndef _WANMGR_INTERFACE_SM_H_ +#define _WANMGR_INTERFACE_SM_H_ +/* ---- Global Types -------------------------- */ +#include +#include +#include +#include +#include +#include +#include "wanmgr_rdkbus_common.h" +#include "wanmgr_data.h" + +#define WAN_STATUS_UP "up" +#define WAN_STATUS_DOWN "down" + +#include +extern int sysevent_fd; +extern token_t sysevent_token; + + +typedef enum +{ + WANMGR_IFACE_LINK_UP = 0, + WANMGR_IFACE_LINK_DOWN, + WANMGR_IFACE_CONNECTION_UP, + WANMGR_IFACE_CONNECTION_DOWN, + WANMGR_IFACE_CONNECTION_IPV6_UP, + WANMGR_IFACE_CONNECTION_IPV6_DOWN, +#ifdef FEATURE_MAPT + WANMGR_IFACE_MAPT_START, + WANMGR_IFACE_MAPT_STOP, +#endif //FEATURE_MAPT + WANMGR_IFACE_STATUS_ERROR +}wanmgr_iface_status_t; + + + +typedef struct WanMgr_IfaceSM_Ctrl_st +{ + BOOL WanEnable; + INT interfaceIdx; +#ifdef FEATURE_IPOE_HEALTH_CHECK + UINT IhcPid; +#endif + DML_WAN_IFACE* pIfaceData; +} WanMgr_IfaceSM_Controller_t; + + + + +void WanManager_UpdateInterfaceStatus(DML_WAN_IFACE* pIfaceData, wanmgr_iface_status_t iface_status); + +void WanMgr_IfaceSM_Init(WanMgr_IfaceSM_Controller_t* pWanIfaceSMCtrl, INT iface_idx); +int WanMgr_StartInterfaceStateMachine(WanMgr_IfaceSM_Controller_t *wanIf); + +#endif /*_WANMGR_INTERFACE_SM_H_*/ diff --git a/source/WanManager/wanmgr_ipc.c b/source/WanManager/wanmgr_ipc.c new file mode 100644 index 00000000..39917e77 --- /dev/null +++ b/source/WanManager/wanmgr_ipc.c @@ -0,0 +1,488 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2015 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +/* ---- Include Files ---------------------------------------- */ +#include +#include +#include +#include "wanmgr_ipc.h" +#include "wanmgr_data.h" +#include "wanmgr_sysevents.h" +#include "wanmgr_net_utils.h" +#include "wanmgr_dhcpv4_apis.h" +#include "wanmgr_interface_sm.h" + + +#define WANMGR_MAX_IPC_PROCCESS_TRY 5 +#define WANMGR_IPC_PROCCESS_TRY_WAIT_TIME 30000 //us + + +typedef struct _WanIpcCtrl_t_ +{ + INT interfaceIdx; +} WanIpcCtrl_t; + + +static int ipcListenFd; /* Unix domain IPC listening socket fd */ +extern int sysevent_fd; +extern token_t sysevent_token; + + +/* ---- Private Functions ------------------------------------ */ +#ifdef FEATURE_IPOE_HEALTH_CHECK +static ANSC_STATUS ProcessIpoeHealthCheckFailedIpv4Msg(char * ifName); +static ANSC_STATUS ProcessIpoeHealthCheckFailedRenewIpv4Msg(char * ifName); +static ANSC_STATUS ProcessIpoeHealthCheckFailedIpv6Msg(char * ifName); +static ANSC_STATUS ProcessIpoeHealthCheckFailedRenewIpv6Msg(char * ifName); +#endif /*FEATURE_IPOE_HEALTH_CHECK*/ + + + +/* ---- Private Variables ------------------------------------ */ + + + +//ANSC_STATUS WanManager_sendIpcMsgToClient_AndGetReplyWithTimeout(ipc_msg_payload_t * payload) +//{ +// return ANSC_STATUS_SUCCESS; +//} +// +// +//ANSC_STATUS WanManager_sendIpcMsgToClient(ipc_msg_payload_t * payload) +//{ +// return ANSC_STATUS_SUCCESS; +//} + + +static ANSC_STATUS WanMgr_IpcNewIpv4Msg(ipc_dhcpv4_data_t* pNewIpv4Msg) +{ + ANSC_STATUS retStatus = ANSC_STATUS_FAILURE; + INT try = 0; + + while((retStatus != ANSC_STATUS_SUCCESS) && (try < WANMGR_MAX_IPC_PROCCESS_TRY)) + { + //get iface data + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceDataByName_locked(pNewIpv4Msg->dhcpcInterface); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pIfaceData = &(pWanDmlIfaceData->data); + + //check if previously message was already handled + if(pIfaceData->IP.pIpcIpv4Data == NULL) + { + //allocate + pIfaceData->IP.pIpcIpv4Data = (ipc_dhcpv4_data_t*) malloc(sizeof(ipc_dhcpv4_data_t)); + if(pIfaceData->IP.pIpcIpv4Data != NULL) + { + // copy data + memcpy(pIfaceData->IP.pIpcIpv4Data, pNewIpv4Msg, sizeof(ipc_dhcpv4_data_t)); + retStatus = ANSC_STATUS_SUCCESS; + } + } + + //release lock + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + + if(retStatus != ANSC_STATUS_SUCCESS) + { + try++; + usleep(WANMGR_IPC_PROCCESS_TRY_WAIT_TIME); + } + } + + return retStatus; +} + + +static ANSC_STATUS WanMgr_IpcNewIpv6Msg(ipc_dhcpv6_data_t* pNewIpv6Msg) +{ + ANSC_STATUS retStatus = ANSC_STATUS_FAILURE; + INT try = 0; + + while((retStatus != ANSC_STATUS_SUCCESS) && (try < WANMGR_MAX_IPC_PROCCESS_TRY)) + { + //get iface data + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceDataByName_locked(pNewIpv6Msg->ifname); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pIfaceData = &(pWanDmlIfaceData->data); + + //check if previously message was already handled + if(pIfaceData->IP.pIpcIpv6Data == NULL) + { + //allocate + pIfaceData->IP.pIpcIpv6Data = (ipc_dhcpv6_data_t*) malloc(sizeof(ipc_dhcpv6_data_t)); + if(pIfaceData->IP.pIpcIpv6Data != NULL) + { + // copy data + memcpy(pIfaceData->IP.pIpcIpv6Data, pNewIpv6Msg, sizeof(ipc_dhcpv6_data_t)); + retStatus = ANSC_STATUS_SUCCESS; + } + } + + //release lock + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + + if(retStatus != ANSC_STATUS_SUCCESS) + { + try++; + usleep(WANMGR_IPC_PROCCESS_TRY_WAIT_TIME); + } + } + + return retStatus; +} + +#ifdef FEATURE_IPOE_HEALTH_CHECK + +static ANSC_STATUS WanMgr_IpcNewIhcMsg(ipc_ihc_data_t *pIhcMsg) +{ + if (pIhcMsg == NULL) + { + CcspTraceError(("[%s-%d] Failed to process IPoE v6 Echo Renew Event \n", __FUNCTION__, __LINE__)); + return ANSC_STATUS_FAILURE; + } + + char conn_status[BUFLEN_16] = {0}; + + switch(pIhcMsg->msgType) + { + case IPOE_MSG_IHC_ECHO_RENEW_IPV6: + CcspTraceInfo(("[%s-%d] Received IPOE_MSG_IHC_ECHO_RENEW_IPV6 from IHC for intf: %s \n", __FUNCTION__, __LINE__, pIhcMsg->ifName)); + if (ProcessIpoeHealthCheckFailedRenewIpv6Msg(pIhcMsg->ifName) != ANSC_STATUS_SUCCESS) + { + CcspTraceError(("[%s-%d] Failed to process IPoE v6 Echo Renew Event \n", __FUNCTION__, __LINE__)); + return ANSC_STATUS_FAILURE; + } + break; + case IPOE_MSG_IHC_ECHO_RENEW_IPV4: + CcspTraceInfo(("[%s-%d] Received IPOE_MSG_IHC_ECHO_RENEW_IPV4 from IHC for intf: %s \n", __FUNCTION__, __LINE__, pIhcMsg->ifName)); + if (ProcessIpoeHealthCheckFailedRenewIpv4Msg(pIhcMsg->ifName) != ANSC_STATUS_SUCCESS) + { + CcspTraceError(("[%s-%d] Failed to process IPoE v6 Echo Renew Event \n", __FUNCTION__, __LINE__)); + return ANSC_STATUS_FAILURE; + } + break; + case IPOE_MSG_IHC_ECHO_IPV6_UP: + /* Check if we get the IPv6 connection UP message from the + IPOE Health Check, in case the IPV6 status is DOWN set + it to UP. + */ + CcspTraceInfo(("[%s-%d] Received IPOE_MSG_IHC_ECHO_IPV6_UP from IHC for intf: %s \n", __FUNCTION__, __LINE__, pIhcMsg->ifName)); + sysevent_get(sysevent_fd, sysevent_token, SYSEVENT_IPV6_CONNECTION_STATE, conn_status, sizeof(conn_status)); + if(strcmp(conn_status, WAN_STATUS_DOWN) == 0) + { + CcspTraceInfo(("Setting IPV6 Connection state to UP \n")); + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_IPV6_CONNECTION_STATE, WAN_STATUS_UP, 0); + } + break; + case IPOE_MSG_IHC_ECHO_IPV4_UP: + /* Check if we get the IPv4 connection UP message from the + IPOE Health Check, in case the IPv4 status is DOWN, set + it to UP. + */ + CcspTraceInfo(("[%s-%d] Received IPOE_MSG_IHC_ECHO_IPV4_UP from IHC for intf: %s \n", __FUNCTION__, __LINE__, pIhcMsg->ifName)); + sysevent_get(sysevent_fd, sysevent_token, SYSEVENT_IPV4_CONNECTION_STATE, conn_status, sizeof(conn_status)); + if(strcmp(conn_status, WAN_STATUS_DOWN) == 0) + { + CcspTraceInfo(("Setting IPv4 Connection state to UP \n")); + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_IPV4_CONNECTION_STATE, WAN_STATUS_UP, 0); + } + break; + case IPOE_MSG_IHC_ECHO_FAIL_IPV4: + CcspTraceInfo(("[%s-%d] Received IPOE_MSG_IHC_ECHO_FAIL_IPV4 from IHC for intf: %s \n", __FUNCTION__, __LINE__, pIhcMsg->ifName)); + if(ProcessIpoeHealthCheckFailedIpv4Msg(pIhcMsg->ifName) != ANSC_STATUS_SUCCESS) + { + CcspTraceError(("[%s-%d] Failed to process IPoE v4 Echo Fail Event \n", __FUNCTION__, __LINE__)); + return ANSC_STATUS_FAILURE; + } + break; + case IPOE_MSG_IHC_ECHO_FAIL_IPV6: + CcspTraceInfo(("[%s-%d] Received IPOE_MSG_IHC_ECHO_FAIL_IPV6 from IHC for intf: %s \n", __FUNCTION__, __LINE__, pIhcMsg->ifName)); + if(ProcessIpoeHealthCheckFailedIpv6Msg(pIhcMsg->ifName) != ANSC_STATUS_SUCCESS) + { + CcspTraceError(("[%s-%d] Failed to process IPoE v6 Echo Fail Event \n", __FUNCTION__, __LINE__)); + return ANSC_STATUS_FAILURE; + } + break; + default: + CcspTraceError(("[%s-%d] Invalid message type \n", __FUNCTION__, __LINE__)); + return ANSC_STATUS_FAILURE; + } + return ANSC_STATUS_SUCCESS; +} + +static ANSC_STATUS WanMgr_IpoeSetWanIfData(char *ifName, wanmgr_iface_status_t state) +{ + WanMgr_Iface_Data_t* pWanDmlIfaceData = NULL; + DML_WAN_IFACE* pIfaceData = NULL; + + pWanDmlIfaceData = WanMgr_GetIfaceDataByName_locked(ifName); + if(pWanDmlIfaceData != NULL) + { + pIfaceData = &(pWanDmlIfaceData->data); + WanManager_UpdateInterfaceStatus(pIfaceData, state); + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + return ANSC_STATUS_SUCCESS; + } + return ANSC_STATUS_FAILURE; +} + +static ANSC_STATUS ProcessIpoeHealthCheckFailedIpv4Msg(char *ifName) +{ + + /* Kill DHCPv4 client */ + if (WanManager_StopDhcpv4Client(TRUE) != ANSC_STATUS_SUCCESS) + { + CcspTraceInfo(("Failed to kill DHCPv4 Client \n")); + } + + return WanMgr_IpoeSetWanIfData(ifName, WANMGR_IFACE_CONNECTION_DOWN); +} + +static ANSC_STATUS ProcessIpoeHealthCheckFailedRenewIpv4Msg(char *ifName) +{ + + /*send triggered renew request to DHCPC*/ + if (WanManager_IsApplicationRunning(DHCPV4_CLIENT_NAME) == TRUE) + { + int pid = util_getPidByName(DHCPV4_CLIENT_NAME); + CcspTraceInfo(("sending SIGUSR1 to %s[pid=%d], this will let the %s to send renew packet out \n", DHCPV4_CLIENT_NAME, pid, DHCPV4_CLIENT_NAME)); + util_signalProcess(pid, SIGUSR1); + } + return WanMgr_IpoeSetWanIfData(ifName, WANMGR_IFACE_CONNECTION_DOWN); +} + +static ANSC_STATUS ProcessIpoeHealthCheckFailedIpv6Msg(char *ifName) +{ + + /* Kill DHCPv6 client */ + if (WanManager_StopDhcpv6Client(TRUE) != ANSC_STATUS_SUCCESS) + { + CcspTraceInfo(("Failed to kill DHCPv6 Client \n")); + } + + return WanMgr_IpoeSetWanIfData(ifName, WANMGR_IFACE_CONNECTION_IPV6_DOWN); +} + +static ANSC_STATUS ProcessIpoeHealthCheckFailedRenewIpv6Msg(char *ifName) +{ + + /*send triggered renew request to DHCPv6C*/ + if (WanManager_IsApplicationRunning(DHCPV6_CLIENT_NAME) == TRUE) + { + int pid = util_getPidByName(DHCPV6_CLIENT_NAME); + CcspTraceInfo(("sending SIGUSR2 to dhcp6c, this will let the dhcp6c to send renew packet out \n")); + util_signalProcess(pid, SIGUSR2); + } + + return WanMgr_IpoeSetWanIfData(ifName, WANMGR_IFACE_CONNECTION_IPV6_DOWN); +} + +#endif + + +static void* IpcServerThread( void *arg ) +{ + + //detach thread from caller stack + pthread_detach(pthread_self()); + + // local variables + BOOL bRunning = TRUE; + + int bytes = 0; + int msg_size = sizeof(ipc_msg_payload_t); + ipc_msg_payload_t ipc_msg; + memset (&ipc_msg, 0, sizeof(ipc_msg_payload_t)); + + while (bRunning) + { + bytes = nn_recv(ipcListenFd, (ipc_msg_payload_t *)&ipc_msg, msg_size, 0); + if ((bytes == msg_size)) + { + switch(ipc_msg.msg_type) + { + case DHCPC_STATE_CHANGED: + if (WanMgr_IpcNewIpv4Msg(&(ipc_msg.data.dhcpv4)) != ANSC_STATUS_SUCCESS) + { + CcspTraceError(("[%s-%d] Failed to proccess DHCPv4 state change message \n", __FUNCTION__, __LINE__)); + } + break; + case DHCP6C_STATE_CHANGED: + if (WanMgr_IpcNewIpv6Msg(&(ipc_msg.data.dhcpv6)) != ANSC_STATUS_SUCCESS) + { + CcspTraceError(("[%s-%d] Failed to proccess DHCPv6 state change message \n", __FUNCTION__, __LINE__)); + } + break; +#ifdef FEATURE_IPOE_HEALTH_CHECK + case IHC_STATE_CHANGE: + if (WanMgr_IpcNewIhcMsg(&(ipc_msg.data.ihcData)) != ANSC_STATUS_SUCCESS) + { + CcspTraceError(("[%s-%d] Failed to proccess IHC state change message \n", __FUNCTION__, __LINE__)); + } + break; +#endif + default: + CcspTraceError(("[%s-%d] Invalid Message sent to Wan Manager\n", __FUNCTION__, __LINE__)); + } + } + else + { + CcspTraceError(("[%s-%d] message size unexpected\n", __FUNCTION__, __LINE__)); + } + } + + pthread_exit(NULL); +} + +static ANSC_STATUS IpcServerInit() +{ + ANSC_STATUS ret = ANSC_STATUS_SUCCESS; + uint32_t i; + + if ((ipcListenFd = nn_socket(AF_SP, NN_PULL)) < 0) + { + return ANSC_STATUS_FAILURE; + } + if ((i = nn_bind(ipcListenFd, WAN_MANAGER_ADDR)) < 0) + { + return ANSC_STATUS_FAILURE; + } + + return ANSC_STATUS_SUCCESS; +} + +#ifdef FEATURE_IPOE_HEALTH_CHECK +ANSC_STATUS WanMgr_SendMsgToIHC (ipoe_msg_type_t msgType, char *ifName) +{ + int sock = -1; + int conn = -1; + + ipc_ihc_data_t msgBody; + memset (&msgBody, 0, sizeof(ipc_ihc_data_t)); + msgBody.msgType = msgType; + if (msgType == IPOE_MSG_WAN_CONNECTION_IPV6_UP) + { + // V6 UP Message needs Wan V6 IP + char* pattern = NULL; + char ipv6_prefix[INET6_ADDRSTRLEN] = {0}; + + sysevent_get(sysevent_fd, sysevent_token, SYSCFG_FIELD_IPV6_PREFIX, ipv6_prefix, sizeof(ipv6_prefix)); + if(ipv6_prefix == NULL || *ipv6_prefix == '\0'|| (0 == strncmp(ipv6_prefix, "(null)", strlen("(null)")))) + { + CcspTraceError(("[%s-%d] Unable to get ipv6_prefix..", __FUNCTION__, __LINE__)); + return ANSC_STATUS_FAILURE; + } + + pattern = strstr(ipv6_prefix, "/"); + if (pattern == NULL) + { + CcspTraceError(("[%s-%d] Invalid ipv6_prefix :%s", ipv6_prefix)); + return ANSC_STATUS_FAILURE; + } + sprintf(pattern, "%c%c", '1', '\0'); //Form the global address with ::1 + strncpy(msgBody.ipv6Address, ipv6_prefix, sizeof(ipv6_prefix)); + CcspTraceInfo(("[%s-%d] Sending IPOE_MSG_WAN_CONNECTION_IPV6_UP msg with addr :%s", __FUNCTION__, __LINE__, msgBody.ipv6Address)); + } + else if (msgType == IPOE_MSG_WAN_CONNECTION_UP) + { + char ipv4_wan_address[IP_ADDR_LENGTH] = {0}; + char sysevent_param_name[BUFLEN_64] = {0}; + snprintf(sysevent_param_name, sizeof(sysevent_param_name), SYSEVENT_IPV4_IP_ADDRESS, PHY_WAN_IF_NAME); + sysevent_get(sysevent_fd, sysevent_token, sysevent_param_name, ipv4_wan_address, sizeof(ipv4_wan_address)); + if(ipv4_wan_address == NULL || *ipv4_wan_address == '\0'|| (0 == strncmp(ipv4_wan_address, "(null)", strlen("(null)")))) + { + CcspTraceError(("[%s-%d] Unable to get ipv4_erouter0_ipaddr..", __FUNCTION__, __LINE__)); + return ANSC_STATUS_FAILURE; + } + strncpy(msgBody.ipv4Address, ipv4_wan_address, sizeof(ipv4_wan_address)); + CcspTraceInfo(("[%s-%d] Sending IPOE_MSG_WAN_CONNECTION_UP msg with addr :%s", __FUNCTION__, __LINE__, msgBody.ipv4Address)); + } + strncpy(msgBody.ifName, ifName, IFNAME_LENGTH); + + CcspTraceInfo(("[%s-%d] Sending msg = %d for interface %s \n", __FUNCTION__, __LINE__, msgType, ifName)); + + int bytes = 0; + int msgSize = sizeof(ipc_ihc_data_t); + + sock = nn_socket(AF_SP, NN_PUSH); + if (sock < 0) + { + CcspTraceError(("[%s-%d] nn_socket failed")); + return ANSC_STATUS_FAILURE; + } + + conn = nn_connect(sock, IHC_IPC_ADDR); + if (conn < 0) + { + CcspTraceError(("[%s-%d] Failed to connect to the IPoE HEalth Check IPC socket \n", __FUNCTION__, __LINE__)); + nn_close (sock); + return ANSC_STATUS_FAILURE; + } + bytes = nn_send(sock, (char *) &msgBody, msgSize, 0); + if (bytes < 0) + { + CcspTraceError(("[%s-%d] Failed to send data to IPoE HEalth Check error=[%d][%s] \n", __FUNCTION__, __LINE__,errno, strerror(errno))); + nn_close (sock); + return ANSC_STATUS_FAILURE; + } + + CcspTraceInfo(("[%s-%d] Successfully send %d bytes over nano msg \n", __FUNCTION__, __LINE__,bytes)); + nn_close (sock); + return ANSC_STATUS_SUCCESS; +} +#endif + + +ANSC_STATUS WanMgr_StartIpcServer() +{ + pthread_t ipcThreadId; + ANSC_STATUS retStatus = ANSC_STATUS_FAILURE; + int ret = -1; + + if(IpcServerInit() != ANSC_STATUS_SUCCESS) + { + CcspTraceInfo(("Failed to initialise IPC messaging")); + return -1; + } + + //create thread + ret = pthread_create( &ipcThreadId, NULL, &IpcServerThread, NULL ); + + if( 0 != ret ) + { + CcspTraceInfo(("%s %d - Failed to start IPC Thread Error:%d\n", __FUNCTION__, __LINE__, ret)); + } + else + { + CcspTraceInfo(("%s %d - IPC Thread Started Successfully\n", __FUNCTION__, __LINE__)); + retStatus = ANSC_STATUS_SUCCESS; + } + return retStatus ; +} + +ANSC_STATUS WanMgr_CloseIpcServer(void) +{ + //nn_close(ipcListenFd); + + return ANSC_STATUS_SUCCESS ; +} diff --git a/source/WanManager/wanmgr_ipc.h b/source/WanManager/wanmgr_ipc.h new file mode 100644 index 00000000..84a833ed --- /dev/null +++ b/source/WanManager/wanmgr_ipc.h @@ -0,0 +1,37 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2015 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +#ifndef _WANMGR_IPC_H_ +#define _WANMGR_IPC_H_ + + +#include "ansc_platform.h" +#include "ipc_msg.h" + + +#ifdef FEATURE_IPOE_HEALTH_CHECK +ANSC_STATUS WanMgr_SendMsgToIHC (ipoe_msg_type_t msgType, char *ifName); +#endif + + +ANSC_STATUS WanMgr_StartIpcServer(); /*IPC server to handle WAN Manager clients*/ +ANSC_STATUS WanMgr_CloseIpcServer(void); + + +#endif /*_WANMGR_IPC_H_*/ diff --git a/source/WanManager/wanmgr_main.c b/source/WanManager/wanmgr_main.c new file mode 100644 index 00000000..ef13b365 --- /dev/null +++ b/source/WanManager/wanmgr_main.c @@ -0,0 +1,379 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2017 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +/********************************************************************** + Copyright [2014] [Cisco Systems, Inc.] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +**********************************************************************/ + +/********************************************************************************* + + description: + + This is the template file of ssp_main.c for XxxxSsp. + Please replace "XXXX" with your own ssp name with the same up/lower cases. + + ------------------------------------------------------------------------------ + + revision: + + 09/08/2011 initial revision. + +**********************************************************************************/ + + +#ifdef __GNUC__ +#ifndef _BUILD_ANDROID +#include +#endif +#endif + +#include "wanmgr_ssp_global.h" +#include "wanmgr_core.h" +#include "wanmgr_data.h" +#include "stdlib.h" +#include "ccsp_dm_api.h" + +#define DEBUG_INI_NAME "/etc/debug.ini" + +#ifdef ENABLE_SD_NOTIFY +#include +#endif + +#ifdef INCLUDE_BREAKPAD +#include "breakpad_wrapper.h" +#endif + +extern char* pComponentName; +char g_Subsystem[32] = {0}; + +int cmd_dispatch(int command) +{ + switch ( command ) + { + case 'e' : + +#ifdef _ANSC_LINUX + CcspTraceInfo(("Connect to bus daemon...\n")); + + { + char CName[256]; + + if ( g_Subsystem[0] != 0 ) + { + _ansc_sprintf(CName, "%s%s", g_Subsystem, COMPONENT_ID_WANMANAGER); + } + else + { + _ansc_sprintf(CName, "%s", COMPONENT_ID_WANMANAGER); + } + + ssp_Mbi_MessageBusEngage + ( + CName, + CCSP_MSG_BUS_CFG, + COMPONENT_PATH_WANMANAGER + ); + } +#endif + + ssp_create(); + ssp_engage(); + + break; + + case 'm': + + AnscPrintComponentMemoryTable(pComponentName); + + break; + + case 't': + + AnscTraceMemoryTable(); + + break; + + case 'c': + + ssp_cancel(); + + break; + + default: + break; + } + + return 0; +} + +static void _print_stack_backtrace(void) +{ +#ifdef __GNUC__ +#ifndef _BUILD_ANDROID + void* tracePtrs[100]; + char** funcNames = NULL; + int i, count = 0; + + count = backtrace( tracePtrs, 100 ); + backtrace_symbols_fd( tracePtrs, count, 2 ); + + funcNames = backtrace_symbols( tracePtrs, count ); + + if ( funcNames ) { + // Print the stack trace + for( i = 0; i < count; i++ ) + printf("%s\n", funcNames[i] ); + + // Free the string pointers + free( funcNames ); + } +#endif +#endif +} + +#if defined(_ANSC_LINUX) +static void daemonize(void) { + int fd; + switch (fork()) { + case 0: + break; + case -1: + // Error + CcspTraceInfo(("Error daemonizing (fork)! %d - %s\n", errno, strerror( + errno))); + exit(0); + break; + default: + _exit(0); + } + + if (setsid() < 0) { + CcspTraceInfo(("Error demonizing (setsid)! %d - %s\n", errno, strerror(errno))); + exit(0); + } + +// chdir("/"); + + +#ifndef _DEBUG + + fd = open("/dev/null", O_RDONLY); + if (fd != 0) { + dup2(fd, 0); + close(fd); + } + fd = open("/dev/null", O_WRONLY); + if (fd != 1) { + dup2(fd, 1); + close(fd); + } + fd = open("/dev/null", O_WRONLY); + if (fd != 2) { + dup2(fd, 2); + close(fd); + } +#endif +} + +void sig_handler(int sig) +{ + if ( sig == SIGINT ) { + signal(SIGINT, sig_handler); /* reset it to this function */ + CcspTraceInfo(("SIGINT received!\n")); + exit(0); + } + else if ( sig == SIGUSR1 ) { + signal(SIGUSR1, sig_handler); /* reset it to this function */ + CcspTraceInfo(("SIGUSR1 received!\n")); + } + else if ( sig == SIGUSR2 ) { + CcspTraceInfo(("SIGUSR2 received!\n")); + } + else if ( sig == SIGCHLD ) { + signal(SIGCHLD, sig_handler); /* reset it to this function */ + CcspTraceInfo(("SIGCHLD received!\n")); + } + else if ( sig == SIGPIPE ) { + signal(SIGPIPE, sig_handler); /* reset it to this function */ + CcspTraceInfo(("SIGPIPE received!\n")); + } + else { + /* get stack trace first */ + _print_stack_backtrace(); + CcspTraceInfo(("Signal %d received, exiting!\n", sig)); + exit(0); + } + +} + +#endif +int main(int argc, char* argv[]) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + BOOL bRunAsDaemon = TRUE; + int cmdChar = 0; + int idx = 0; + char cmd[1024] = {0}; + FILE *fd = NULL; + + extern ANSC_HANDLE bus_handle; + char *subSys = NULL; + DmErr_t err; + + + for (idx = 1; idx < argc; idx++) + { + if ( (strcmp(argv[idx], "-subsys") == 0) ) + { + AnscCopyString(g_Subsystem, argv[idx+1]); + } + else if ( strcmp(argv[idx], "-c") == 0 ) + { + bRunAsDaemon = FALSE; + } + } + + pComponentName = COMPONENT_NAME_WANMANAGER; + + //DATA INIT + WanMgr_Data_Init(); + +#if defined(_ANSC_WINDOWSNT) + + AnscStartupSocketWrapper(NULL); + + cmd_dispatch('e'); + + while ( cmdChar != 'q' ) + { + cmdChar = getchar(); + + cmd_dispatch(cmdChar); + } +#elif defined(_ANSC_LINUX) + if ( bRunAsDaemon ) + daemonize(); + + fd = fopen("/var/tmp/wanmanager.pid", "w+"); + if ( !fd ) + { + CcspTraceWarning(("Create /var/tmp/wanmanager.pid error. \n")); + return 1; + } + else + { + sprintf(cmd, "%d", getpid()); + fputs(cmd, fd); + fclose(fd); + } + +#ifdef INCLUDE_BREAKPAD + breakpad_ExceptionHandler(); +#else + signal(SIGTERM, sig_handler); + signal(SIGINT, sig_handler); + /*signal(SIGCHLD, sig_handler);*/ + signal(SIGUSR1, sig_handler); + signal(SIGUSR2, sig_handler); + + signal(SIGSEGV, sig_handler); + signal(SIGBUS, sig_handler); + signal(SIGKILL, sig_handler); + signal(SIGFPE, sig_handler); + signal(SIGILL, sig_handler); + signal(SIGQUIT, sig_handler); + signal(SIGHUP, sig_handler); +#endif //INCLUDE_BREAKPAD + + cmd_dispatch('e'); +#ifdef _COSA_SIM_ + subSys = ""; /* PC simu use empty string as subsystem */ +#else + subSys = NULL; /* use default sub-system */ +#endif //_COSA_SIM_ + err = Cdm_Init(bus_handle, subSys, NULL, NULL, pComponentName); + if (err != CCSP_SUCCESS) + { + fprintf(stderr, "Cdm_Init: %s\n", Cdm_StrError(err)); + exit(1); + } + //rdk_logger_init("/fss/gw/lib/debug.ini"); + rdk_logger_init(DEBUG_INI_NAME); + +#ifdef ENABLE_SD_NOTIFY + sd_notifyf(0, "READY=1\n" + "STATUS=wanmanager is Successfully Initialized\n" + "MAINPID=%lu", (unsigned long) getpid()); + + CcspTraceInfo(("RDKB_SYSTEM_BOOT_UP_LOG : wanmanager sd_notify Called\n")); +#endif //ENABLE_SD_NOTIFY + + system("touch /tmp/wanmanager_initialized"); + + + //CORE INT + WanMgr_Core_Init(); + + if ( bRunAsDaemon ) + { + //MAIN THREAD + WanMgr_Core_Start(); + } + else + { + while ( cmdChar != 'q' ) + { + cmdChar = getchar(); + + cmd_dispatch(cmdChar); + } + } + +#endif + + //CORE FINALISE + WanMgr_Core_Finalise(); + + err = Cdm_Term(); + if (err != CCSP_SUCCESS) + { + fprintf(stderr, "Cdm_Term: %s\n", Cdm_StrError(err)); + exit(1); + } + + ssp_cancel(); + + //DATA DELETE + WanMgr_Data_Delete(); + + return 0; +} + diff --git a/source/WanManager/wanmgr_net_utils.c b/source/WanManager/wanmgr_net_utils.c new file mode 100644 index 00000000..227b5d7c --- /dev/null +++ b/source/WanManager/wanmgr_net_utils.c @@ -0,0 +1,1887 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2015 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +/* ---- Include Files ---------------------------------------- */ +#include /* for inet_pton */ +#include +#include +#include +#include "wanmgr_net_utils.h" +#include "wanmgr_rdkbus_utils.h" +#include "wanmgr_dhcpv4_apis.h" +#include "wanmgr_rdkbus_apis.h" +#include "wanmgr_ssp_internal.h" +#include "ansc_platform.h" +#include +#include +#include +#include "platform_hal.h" +#include + +#define RESOLV_CONF_FILE "/etc/resolv.conf" +#define LOOPBACK "127.0.0.1" +#define BROADCAST_IP "255.255.255.255" +/* To ignore link local addresses configured as DNS servers, + * it covers the range 169.254.x.x */ +#define LINKLOCAL_RANGE "169.254" +/* To ignore loopback addresses configured as DNS servers, + * it covers the range 127.x.x.x */ +#define LOOPBACK_RANGE "127" + +#define BASE_IFNAME_PPPoA "atm0" +#define BASE_IFNAME_PPPoE "vlan101" +#define DEFAULT_IFNAME "erouter0" + +/** Macro to determine if a string parameter is empty or not */ +#define IS_EMPTY_STR(s) ((s == NULL) || (*s == '\0')) + +#define DHCPV4C_PID_FILE "/tmp/erouter_dhcp4c.pid" +#define MTU_SIZE (1520) +#define MTU_DEFAULT_SIZE (1500) +#define DHCPV6_OPTION_STR_LEN 288 +#define DEFAULT_SER_FIELD_LEN 64 +#define DHCPV6_OPTIONS_FILE "/var/skydhcp6_options.txt" +#ifdef FEATURE_IPOE_HEALTH_CHECK +#define DHCP6C_RENEW_PREFIX_FILE "/tmp/erouter0.dhcpc6c_renew_prefix.conf" +#endif + +/** Some defines for selecting which address family (IPv4 or IPv6) we want. + * Note: are bits for use in bitmasks (not integers) + */ +#define AF_SELECT_IPV4 0x0001 +#define AF_SELECT_IPV6 0x0002 + +extern ANSC_HANDLE bus_handle; + +#define DATAMODEL_PARAM_LENGTH 256 + +#define SYSCFG_WAN_INTERFACE_NAME "wan_physical_ifname" +#define DUID_CLIENT "/tmp/dibbler/client-duid" +#define DUID_TYPE "00:03:" /* duid-type duid-ll 3 */ +#define HW_TYPE "00:01:" /* hw type is always 1 */ +#define DIBBLER_IPV6_CLIENT_ENABLE "Device.DHCPv6.Client.%d.Enable" + +/*************************************************************************** + * @brief API used to check the incoming nameserver is valid + * @param af indicates ip address family + * @param nameserver dns namserver name + * @return RETURN_OK if execution successful else returned error. + ****************************************************************************/ +static int IsValidDnsServer(int32_t af, const char *nameServer); + +/*************************************************************************** + * @brief API used to check the incoming ipv4 address is a valid ipv4 address + * @param input string contains ipv4 address + * @return TRUE if its a valid IP address else returned false. + ****************************************************************************/ +static BOOL IsValidIpv4Address(const char *input); + +/*************************************************************************** + * @brief API used to check the incoming ip address is a valid one + * @param ipvx ip address family either v4 or v6 + * @param addr string contains ip address + * @return TRUE if its a valid IP address else returned false. + ****************************************************************************/ +static BOOL IsZeroIpvxAddress(uint32_t ipvx, const char *addr); + +/*************************************************************************** + * @brief API used to check the incoming ipv address is a valid. + * @param af indicates address family + * @param address string contains ip address + * @return TRUE if its a valid IP address else returned false. + ****************************************************************************/ +static BOOL IsValidIpAddress(int32_t af, const char *address); + +/*************************************************************************** + * @brief API used to parse ipv6 prefix address + * @param prefixAddr ipv6 prefix address + * @param address string contains ip address + * @param plen holds length of the prefix address + * @return TRUE if its a valid IP address else returned false. + ****************************************************************************/ +static int ParsePrefixAddress(const char *prefixAddr, char *address, uint32_t *plen); + + +/*************************************************************************** + * @brief API used to enable/disable dibbler client + * @param enable boolean contains enable flag + * @return ANSC_STATUS_SUCCESS if the operation is successful + * @return ANSC_STATUS_FAILURE if the operation is failure + ****************************************************************************/ +static ANSC_STATUS setDibblerClientEnable(BOOL * enable); + +#ifdef _HUB4_PRODUCT_REQ_ +/*************************************************************************** + * @brief API used to get ADSL username and password + * @param Username: ADSL username + * @param Password: ADSL Password + * @return TRUE if ADSL Username and Password is read from file else returned false. + ****************************************************************************/ +#define SERIALIZATION_DATA "/tmp/serial.txt" +static ANSC_STATUS GetAdslUsernameAndPassword(char *Username, char *Password); +#endif + + /*************************************************************************** + * @brief Thread that sets enable/disable data model of dhcpv6 client + * @param arg: enable/disable flag to start and stop dhcp6c client + ****************************************************************************/ +static void* Dhcpv6HandlingThread( void *arg ); +static int get_index_from_path(const char *path); +static void* DmlHandlePPPCreateRequestThread( void *arg ); +static void generate_client_duid_conf(); +static void createDummyWanBridge(); +static void deleteDummyWanBridgeIfExist(); + +static ANSC_STATUS SetDataModelParamValues( char *pComponent, char *pBus, char *pParamName, char *pParamVal, enum dataType_e type, BOOLEAN bCommit ) +{ + CCSP_MESSAGE_BUS_INFO *bus_info = (CCSP_MESSAGE_BUS_INFO *)bus_handle; + parameterValStruct_t param_val[1] = { 0 }; + char *faultParam = NULL; + int ret = 0; + + //Copy Name + param_val[0].parameterName = pParamName; + //Copy Value + param_val[0].parameterValue = pParamVal; + + //Copy Type + param_val[0].type = type; + ret = CcspBaseIf_setParameterValues( + bus_handle, + pComponent, + pBus, + 0, + 0, + param_val, + 1, + bCommit, + &faultParam + ); + + if( ( ret != CCSP_SUCCESS ) && ( faultParam != NULL ) ) + { + CcspTraceError(("%s-%d Failed to set %s\n",__FUNCTION__,__LINE__,pParamName)); + bus_info->freefunc( faultParam ); + return ANSC_STATUS_FAILURE; + } + + return ANSC_STATUS_SUCCESS; +} + + +static ANSC_STATUS setDibblerClientEnable(BOOL *enable) +{ + INT index = 0; + pthread_t dibblerThreadId; + INT iErrorCode = -1; + + iErrorCode = pthread_create( &dibblerThreadId, NULL, &Dhcpv6HandlingThread, (void*)enable ); + if( 0 != iErrorCode ) + { + CcspTraceInfo(("%s %d - Dhcpv6HandlingThread thread failed. EC:%d\n", __FUNCTION__, __LINE__, iErrorCode )); + return ANSC_STATUS_FAILURE; + } + + return ANSC_STATUS_SUCCESS; +} + +static void* Dhcpv6HandlingThread( void *arg ) +{ + char ParamName[BUFLEN_256] = {0}; + char ParamValue[BUFLEN_256] = {0}; + + //detach thread from caller stack + pthread_detach(pthread_self()); + + BOOL *enable_client = (BOOL *) arg; + + if( NULL == enable_client ) + { + CcspTraceError(("%s Invalid Memory\n", __FUNCTION__)); + pthread_exit(NULL); + } + + snprintf( ParamName, BUFLEN_256, DIBBLER_IPV6_CLIENT_ENABLE, 1 ); + if(*enable_client) + snprintf( ParamValue, BUFLEN_256, "%s", "true"); + else + snprintf( ParamValue, BUFLEN_256, "%s", "false"); + + SetDataModelParamValues( WAN_COMPONENT_NAME, COMPONENT_PATH_WANMANAGER, ParamName, ParamValue, ccsp_boolean, TRUE ); + + CcspTraceInfo(("%s %d Successfully set %d value to %s data model \n", __FUNCTION__, __LINE__, *enable_client, ParamName)); + + pthread_exit(NULL); +} + + +int WanManager_Ipv6AddrUtil(char *ifname, Ipv6OperType opr, int preflft, int vallft) +{ + struct ifaddrs *ifap, *ifa; + char addr[INET6_ADDRSTRLEN] = {0}; + char cmdLine[128] = {0}; + + if (getifaddrs(&ifap) == -1) + { + return -1; + } + + for (ifa = ifap; ifa; ifa = ifa->ifa_next) + { + if (strncmp(ifa->ifa_name, ifname, strlen(ifname))) + continue; + if (ifa->ifa_addr->sa_family != AF_INET6) + continue; + getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in6), addr, + sizeof(addr), NULL, 0, NI_NUMERICHOST); + if ((strncmp(addr, "fe", 2) != 0) && (strncmp(addr, "fd", 2) != 0)) + { + switch (opr) + { + case DEL_ADDR: + { + memset(cmdLine, 0, sizeof(cmdLine)); + snprintf(cmdLine, sizeof(cmdLine), "ip -6 addr del %s/64 dev %s", addr, ifname); + if (WanManager_DoSystemActionWithStatus("ip -6 addr del ADDR dev xxxx", cmdLine) != 0) + CcspTraceError(("failed to run cmd: %s", cmdLine)); + memset(cmdLine, 0, sizeof(cmdLine)); + snprintf(cmdLine, sizeof(cmdLine), "ip -6 route del %s/64 dev %s", addr, ifname); + if (WanManager_DoSystemActionWithStatus("ip -6 route del ADDR dev xxxx", cmdLine) != 0) + CcspTraceError(("failed to run cmd: %s", cmdLine)); + break; + } + case SET_LFT: + { + memset(cmdLine, 0, sizeof(cmdLine)); + snprintf(cmdLine, sizeof(cmdLine), "ip -6 addr change %s dev brlan0 valid_lft %d preferred_lft %d ", addr, vallft, preflft); + if (WanManager_DoSystemActionWithStatus("processDhcp6cStateChanged: ip -6 addr change L3IfName", (cmdLine)) != 0) + CcspTraceError(("failed to run cmd: %s", cmdLine)); + break; + } + } + } + } + freeifaddrs(ifap); + return 0; +} + + + + +ANSC_STATUS WanManager_StartDhcpv6Client(const char *pcInterfaceName, BOOL isPPP) +{ + char cmdLine[BUFLEN_128]; + bool enableClient = TRUE; + + CcspTraceInfo(("Enter WanManager_StartDhcpv6Client for %s \n", DHCPV6_CLIENT_NAME)); + sprintf(cmdLine, "%s start", DHCPV6_CLIENT_NAME); + system(cmdLine); + CcspTraceInfo(("Started %s \n", cmdLine )); + if(setDibblerClientEnable(&enableClient) == ANSC_STATUS_SUCCESS) + { + CcspTraceInfo(("setDibblerClientEnable is successful \n")); + } + else + { + CcspTraceInfo(("setDibblerClientEnable is failure \n")); + } + + return ANSC_STATUS_SUCCESS; +} + +/** + * @brief This function will stop the DHCPV6 client(WAN side) in router + * + * @param boolDisconnect : This indicates whether this function called from disconnect context or not. + * TRUE (disconnect context) / FALSE (Non disconnect context) + */ +ANSC_STATUS WanManager_StopDhcpv6Client(BOOL boolDisconnect) +{ + ANSC_STATUS ret = ANSC_STATUS_SUCCESS; + char cmdLine[BUFLEN_128]; + + CcspTraceInfo(("Enter WanManager_StopDhcpv6Client for %s \n", DHCPV6_CLIENT_NAME)); + sprintf(cmdLine, "killall %s", DHCPV6_CLIENT_NAME); + system(cmdLine); + + CcspTraceInfo(("Exit WanManager_StopDhcpv6Client\n")); + return ret; +} + +uint32_t WanManager_StartDhcpv4Client(const char *intf, BOOL discover) +{ + uint32_t pid = 0; + char cmdLine[BUFLEN_128]; + char exeBuff[1024] = {0}; + + /** + * In case of udhcpc, we are passing action handler program which will be invoked + * and fill the required dhcpv4 configuration. This handler will pass the data back + * to wanmanager. Get full path of the action handler executable and pass to udhcpc. + */ + if (ANSC_STATUS_SUCCESS != GetPathToApp(DHCPV4_ACTION_HANDLER, exeBuff, sizeof(exeBuff) - 1)) + { + CcspTraceError(("Could not find requested app [%s] in CPE , not passing -s option to udhcpc \n", DHCPV4_ACTION_HANDLER)); + snprintf(cmdLine, sizeof(cmdLine), "-f -i %s -p %s", (intf != NULL ? intf : ""),DHCPV4C_PID_FILE); + } + else + { + snprintf(cmdLine, sizeof(cmdLine), "-f -i %s -p %s -s %s", (intf != NULL ? intf : ""),DHCPV4C_PID_FILE, exeBuff); + } + + pid = WanManager_DoStartApp(DHCPV4_CLIENT_NAME, cmdLine); + + return pid; +} + +ANSC_STATUS WanManager_StopDhcpv4Client(BOOL sendReleaseAndExit) +{ + CcspTraceInfo(("Enter WanManager_StopDhcpv4Client for %s \n", DHCPV4_CLIENT_NAME)); + ANSC_STATUS ret = ANSC_STATUS_SUCCESS; + + if (!sendReleaseAndExit) + { + WanManager_DoStopApp(DHCPV4_CLIENT_NAME); + } + else + { + CcspTraceInfo(("Sending release and exit msg to %s \n", DHCPV4_CLIENT_NAME)); + if (WanManager_IsApplicationRunning(DHCPV4_CLIENT_NAME) == TRUE) + { + int pid = util_getPidByName(DHCPV4_CLIENT_NAME); + CcspTraceInfo(("sending SIGUSR2 to [%s][pid=%d], this will let the %s to send release packet out and exit \n", DHCPV4_CLIENT_NAME)); + if (util_signalProcess(pid, SIGUSR2) != RETURN_OK) + { + WanManager_DoStopApp(DHCPV4_CLIENT_NAME); + } + else + { + /* Collect if any zombie process. */ + WanManager_DoCollectApp(DHCPV4_CLIENT_NAME); + } + } + } + + return ret; +} + +void WanUpdateDhcp6cProcessId(char *currentBaseIfName) +{ + INT wanIndex = -1; + int processId = 0; + char cmdLine[BUFLEN_128]; + char out[BUFLEN_128] = {0}; + + sprintf(cmdLine, "pidof %s", DHCPV6_CLIENT_NAME); + _get_shell_output(cmdLine, out, sizeof(out)); + CcspTraceError(("%s Updating dibbler client pid %s\n", __func__, out)); + processId = atoi(out); + + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceDataByName_locked(currentBaseIfName); + if (pWanDmlIfaceData != NULL) + { + pWanDmlIfaceData->data.IP.Dhcp6cPid = processId; + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + else + { + CcspTraceError(("%s Failed to get index for %s\n", __FUNCTION__, currentBaseIfName)); + return; + } +} + +#ifdef FEATURE_MAPT +const char *nat44PostRoutingTable = "OUTBOUND_POSTROUTING"; +char ipv6AddressString[BUFLEN_256] = " "; +#ifdef FEATURE_MAPT_DEBUG +void WanManager_UpdateMaptLogFile(Dhcp6cMAPTParametersMsgBody *dhcp6cMAPTMsgBody); +#endif // FEATURE_MAPT_DEBUG +static int WanManager_CalculateMAPTPsid(char *pdIPv6Prefix, int v6PrefixLen, int iapdPrefixLen, int v4PrefixLen, int *psidValue, int *ipv4IndexValue, int *psidLen); +static int WanManager_ConfigureIpv6Sysevents(char *pdIPv6Prefix, char *ipAddressString, int psidValue); + +static unsigned WanManager_GetMAPTbits(unsigned value, int pos, int num) +{ + return (value >> (pos + 1 - num)) & ~(~0 << num); +} +/* + * Returns LAN IP Address in the form X.X.X.X/Y, e.g. 192.168.0.1/24 + */ +static ANSC_STATUS WanManager_GetLANIPAddress(char *ipAddress, size_t length) +{ + char lan_ip_address[IP_ADDR_LENGTH] = {0}; + + if (syscfg_get(NULL, SYSCFG_LAN_IP_ADDRESS, lan_ip_address, sizeof(lan_ip_address)) != ANSC_STATUS_SUCCESS) + { + CcspTraceError(("Failed to get LAN IP address \n")); + return ANSC_STATUS_FAILURE; + } + + char lan_subnet_mask[IP_ADDR_LENGTH] = {0}; + + if (syscfg_get(NULL, SYSCFG_LAN_NET_MASK, lan_subnet_mask, sizeof(lan_subnet_mask)) != ANSC_STATUS_SUCCESS) + { + CcspTraceError(("Failed to get LAN subnet mask \n")); + return ANSC_STATUS_FAILURE; + } + + // count number of bits set in subnet mask. + unsigned int lanSubnetMask = inet_network(lan_subnet_mask); + unsigned int subnetCount = 0; + while (lanSubnetMask) + { + subnetCount += lanSubnetMask & 1; + lanSubnetMask = lanSubnetMask >> 1; + } + + CcspTraceInfo(("LAN IP address/subnet mask = %s/%u \n", lan_ip_address, subnetCount)); + + snprintf(ipAddress, length, "%s/%u", lan_ip_address, subnetCount); + + return ANSC_STATUS_SUCCESS; +} + +int WanManager_ProcessMAPTConfiguration(Dhcp6cMAPTParametersMsgBody *dhcp6cMAPTMsgBody, const char *baseIf, const char *vlanIf) +{ + int ret = RETURN_OK; + char cmdDMRConfig[BUFLEN_128 + BUFLEN_64]; + char cmdBMRConfig[BUFLEN_256]; + char cmdStartMAPT[BUFLEN_256]; + char cmdDisableMapFiltering[BUFLEN_64]; + int psidValue = 0; + int ipv4IndexValue = 0; + char ipAddressString[BUFLEN_32] = ""; + char ipLANAddressString[BUFLEN_32] = ""; + struct in_addr result; + unsigned char ipAddressBytes[BUFLEN_4]; + unsigned int ipValue = 0; + int psidLen = 0; + char cmdConfigureMTUSize[BUFLEN_64] = ""; + char cmdEnableIpv4Traffic[BUFLEN_64] = ""; + MaptData_t maptInfo; + + /* RM16042: Since erouter0 is vlan interface on top of eth3, we need + to first set the MTU size of eth3 to 1520 and then change MTU of erouter0. + Otherwise we can't configure MTU as we are getting `Numerical result out of range` error. + Configure eth3 MTU size to 1520. + */ + snprintf(cmdConfigureMTUSize, sizeof(cmdConfigureMTUSize), "ip link set dev %s mtu %d ", baseIf, MTU_SIZE); + +#ifdef FEATURE_MAPT_DEBUG + LOG_PRINT_MAPT("ivictl:cmdConfigureMTUSize:%s", cmdConfigureMTUSize); +#endif + + if ((ret = WanManager_DoSystemActionWithStatus("ivictl", cmdConfigureMTUSize)) < RETURN_OK) + { + CcspTraceError(("Failed to run: %s:%d", cmdConfigureMTUSize, ret)); + return ret; + } + + /* Configure erouter0 MTU size. */ + snprintf(cmdConfigureMTUSize, sizeof(cmdConfigureMTUSize), "ip link set dev %s mtu %d ", vlanIf, MTU_SIZE); + +#ifdef FEATURE_MAPT_DEBUG + LOG_PRINT_MAPT("ivictl:cmdConfigureMTUSize:%s", cmdConfigureMTUSize); +#endif + + if ((ret = WanManager_DoSystemActionWithStatus("ivictl", cmdConfigureMTUSize)) < RETURN_OK) + { + CcspTraceError(("Failed to run: %s:%d", cmdConfigureMTUSize, ret)); + return ret; + } + + snprintf(cmdDMRConfig, sizeof(cmdDMRConfig), "ivictl -r -d -P %s -T", dhcp6cMAPTMsgBody->brIPv6Prefix); +#ifdef FEATURE_MAPT_DEBUG + WanManager_UpdateMaptLogFile(dhcp6cMAPTMsgBody); + LOG_PRINT_MAPT("### ivictl commands - START ###"); + LOG_PRINT_MAPT("ivictl:DMR config:%s", cmdDMRConfig); +#endif + + if ((ret = WanManager_DoSystemActionWithStatus("ivictl", cmdDMRConfig)) < RETURN_OK) + { + CcspTraceError(("Failed to run: %s:%d", cmdDMRConfig, ret)); + return ret; + } + snprintf(cmdBMRConfig, sizeof(cmdBMRConfig), "ivictl -r -p %s -P %s -z %d -R %d -T", dhcp6cMAPTMsgBody->ruleIPv4Prefix, + dhcp6cMAPTMsgBody->ruleIPv6Prefix, dhcp6cMAPTMsgBody->psidOffset, dhcp6cMAPTMsgBody->ratio); + +#ifdef FEATURE_MAPT_DEBUG + LOG_PRINT_MAPT("ivictl:BMR config:%s", cmdBMRConfig); +#endif + + if ((ret = WanManager_DoSystemActionWithStatus("ivictl", cmdBMRConfig)) < RETURN_OK) + { + CcspTraceError(("Failed to run: %s:%d", cmdBMRConfig, ret)); + return ret; + } + + ret = WanManager_CalculateMAPTPsid(dhcp6cMAPTMsgBody->pdIPv6Prefix, dhcp6cMAPTMsgBody->v6Len, dhcp6cMAPTMsgBody->iapdPrefixLen, + dhcp6cMAPTMsgBody->v4Len, &psidValue, &ipv4IndexValue, &psidLen); + + if (ret != RETURN_OK) + { + CcspTraceInfo(("Error in calculating MAPT PSID value")); +#ifdef FEATURE_MAPT_DEBUG + LOG_PRINT_MAPT("Exiting MAPT configuration, MAPT will not be configured, as invalid dhcpc6c options found"); +#endif + CcspTraceNotice(("FEATURE_MAPT: MAP-T configuration failed\n")); + return ret; + } + +#ifdef FEATURE_MAPT_DEBUG + LOG_PRINT_MAPT("ivictl:PSID Value: %d, ipv4IndexValue: %d", psidValue, ipv4IndexValue); +#endif + + inet_pton(AF_INET, dhcp6cMAPTMsgBody->ruleIPv4Prefix, &(result)); + + ipValue = htonl(result.s_addr); + + ipAddressBytes[0] = ipValue & 0xFF; + ipAddressBytes[1] = (ipValue >> 8) & 0xFF; + ipAddressBytes[2] = (ipValue >> 16) & 0xFF; + ipAddressBytes[3] = (ipValue >> 24) & 0xFF; + + if (ipAddressBytes[0] + ipv4IndexValue < 255) + ipAddressBytes[0] += ipv4IndexValue; + else + ipAddressBytes[0] = (ipAddressBytes[0] + ipv4IndexValue) - 255; + + //store new ipv4 address + //dhcp6cMAPTMsgBody->ipv4Address = ( ((ipAddressBytes[3] & 0xFF) << 24) | ((ipAddressBytes[2] & 0xFF) << 16) | ((ipAddressBytes[1] & 0xFF) << 8) | (ipAddressBytes[0] & 0xFF) ); + snprintf(ipAddressString, sizeof(ipAddressString), "%d.%d.%d.%d", ipAddressBytes[3], ipAddressBytes[2], ipAddressBytes[1], ipAddressBytes[0]); + +#ifdef FEATURE_MAPT_DEBUG + LOG_PRINT_MAPT("ipAddressString:%s", ipAddressString); +#endif + + //get LAN IP Address + if ((ret = WanManager_GetLANIPAddress(ipLANAddressString, sizeof(ipLANAddressString))) != RETURN_OK) + { + CcspTraceError(("Could not get LAN IP Address")); + return ret; + } + //The sharing ratio cannot be zero, a value of zero means the sharing ratio is 1 + if (dhcp6cMAPTMsgBody->ratio == 0) + dhcp6cMAPTMsgBody->ratio = 1; + + if ((ret = WanManager_ConfigureIpv6Sysevents(dhcp6cMAPTMsgBody->pdIPv6Prefix, ipAddressString, psidValue)) != RETURN_OK) + { + CcspTraceError(("Failed to configure ipv6Tablerules")); + return ret; + } + // create MAP-T command string + snprintf(cmdStartMAPT, sizeof(cmdStartMAPT), "ivictl -s -i %s -I %s -H -a %s -A %s/%d -P %s -z %d -R %d -T -o %d", ETH_BRIDGE_NAME, vlanIf, + ipLANAddressString, ipAddressString, dhcp6cMAPTMsgBody->v4Len, dhcp6cMAPTMsgBody->ruleIPv6Prefix, dhcp6cMAPTMsgBody->psidOffset, + dhcp6cMAPTMsgBody->ratio, psidValue); + +#ifdef FEATURE_MAPT_DEBUG + LOG_PRINT_MAPT("ivictl:startMapt Command:%s", cmdStartMAPT); +#endif + ret = WanManager_DoSystemActionWithStatus("ivictl", cmdStartMAPT); + + //Added check since the 'system' command is not returning the expected value + if (ret == IVICTL_COMMAND_ERROR) + { + CcspTraceError(("Failed to run: %s:%d", cmdStartMAPT, ret)); + return ret; + } + + snprintf(cmdDisableMapFiltering, sizeof(cmdDisableMapFiltering), "echo 0 > /proc/sys/net/ipv4/conf/%s/rp_filter", vlanIf); + +#ifdef FEATURE_MAPT_DEBUG + LOG_PRINT_MAPT("ivictl:Disable RP Filtering:%s", cmdDisableMapFiltering); +#endif + + if ((ret = WanManager_DoSystemActionWithStatus("ivictl", cmdDisableMapFiltering)) < RETURN_OK) + { + CcspTraceError(("Failed to run: %s:%d", cmdDisableMapFiltering, ret)); + return ret; + } + +#ifdef FEATURE_MAPT_DEBUG + LOG_PRINT_MAPT("ivictl:Calling configureDefaultIpTableRules()... "); +#endif + + /** + * Firewall rules are changed to utopia firewall + * To update the firewall rules, required the MAPT specific values, so + * updated sysvents and restart firewall. + * First set MAPT_CONFIG_FLAG to set, so firewall can add rules for the MAPT configuration. */ + memset(&maptInfo, 0, sizeof(maptInfo)); + strncpy(maptInfo.maptConfigFlag, SET, sizeof(maptInfo.maptConfigFlag)); + strncpy(maptInfo.ruleIpAddressString, dhcp6cMAPTMsgBody->ruleIPv4Prefix, sizeof(maptInfo.ruleIpAddressString)); + strncpy(maptInfo.ruleIpv6AddressString, dhcp6cMAPTMsgBody->ruleIPv6Prefix, sizeof(maptInfo.ruleIpv6AddressString)); + strncpy(maptInfo.brIpv6PrefixString, dhcp6cMAPTMsgBody->brIPv6Prefix, sizeof(maptInfo.brIpv6PrefixString)); + strncpy(maptInfo.ipAddressString, ipAddressString, sizeof(maptInfo.ipAddressString)); + strncpy(maptInfo.ipv6AddressString, ipv6AddressString, sizeof(maptInfo.ipv6AddressString)); + maptInfo.psidValue = psidValue; + maptInfo.psidLen = psidLen; + maptInfo.ratio = dhcp6cMAPTMsgBody->ratio; + maptInfo.psidOffset = dhcp6cMAPTMsgBody->psidOffset; + maptInfo.eaLen = dhcp6cMAPTMsgBody->eaLen; + pthread_mutex_lock(&gmWanDataMutex); + maptInfo.maptAssigned = gWanData.ipv6Data.maptAssigned; + maptInfo.mapeAssigned = gWanData.ipv6Data.mapeAssigned; + maptInfo.isFMR = gWanData.ipv6Data.isFMR; + pthread_mutex_unlock(&gmWanDataMutex); + + if ((ret = maptInfo_set(&maptInfo)) != RETURN_OK) + { + CcspTraceError(("Failed to set sysevents for MAPT feature to set firewall rules \n")); + return ret; + } + + /* Restart firewall to reflect the changes. Do a sysevent to notify firewall to + * restart and update rules. */ + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_FIREWALL_RESTART, NULL, 0); + snprintf(cmdEnableIpv4Traffic, sizeof(cmdEnableIpv4Traffic), "ip ro rep default dev %s", vlanIf); +#ifdef FEATURE_MAPT_DEBUG + LOG_PRINT_MAPT("ivictl:cmdEnableIpv4Traffic:%s", cmdEnableIpv4Traffic); +#endif + if ((ret = WanManager_DoSystemActionWithStatus("ivictl", cmdEnableIpv4Traffic)) < RETURN_OK) + { + CcspTraceError(("Failed to run: %s:%d", cmdEnableIpv4Traffic, ret)); + return ret; + } + +#ifdef FEATURE_MAPT_DEBUG + LOG_PRINT_MAPT("### ivictl commands - ENDS ###"); +#endif + CcspTraceNotice(("FEATURE_MAPT: MAP-T configuration done\n")); + return RETURN_OK; +} + +static int WanManager_CalculateMAPTPsid(char *pdIPv6Prefix, int v6PrefixLen, int iapdPrefixLen, int v4PrefixLen, int *psidValue, int *ipv4IndexValue, int *psidLen) +{ + int ret = RETURN_OK; + int len, startPdOffset, endPdOffset; + int psidByte; + struct in6_addr in6Addr; + int ipv4BitIndexLen; + int psidBitIndexLen; + + startPdOffset = v6PrefixLen; + endPdOffset = iapdPrefixLen; + if (endPdOffset <= startPdOffset) + { +#ifdef FEATURE_MAPT_DEBUG + LOG_PRINT_MAPT("Error: Invalid dhcpc6 option,endPdOffset(%d) has a value which <= startPdOffset(%d)", endPdOffset, startPdOffset); +#endif + CcspTraceError(("Error: Invalid dhcpc6 option,endPdOffset(%d) has a value which <= startPdOffset(%d)", endPdOffset, startPdOffset)); + ret = RETURN_ERR; + return ret; + } + + len = endPdOffset - startPdOffset; + ipv4BitIndexLen = 32 - v4PrefixLen; + psidBitIndexLen = len - ipv4BitIndexLen; + + *psidLen = psidBitIndexLen; + + if (inet_pton(AF_INET6, pdIPv6Prefix, &in6Addr) <= 0) + { + CcspTraceError(("Invalid ipv6 address=%s", pdIPv6Prefix)); + } + + if (len > 8) + { + psidByte = (in6Addr.s6_addr[v6PrefixLen / 8] << 8) | (in6Addr.s6_addr[v6PrefixLen / 8 + 1]); + *ipv4IndexValue = WanManager_GetMAPTbits(psidByte, 15, ipv4BitIndexLen); + *psidValue = WanManager_GetMAPTbits(psidByte, 15 - ipv4BitIndexLen, psidBitIndexLen); + } + else + { + psidByte = in6Addr.s6_addr[v6PrefixLen / 8]; + *ipv4IndexValue = WanManager_GetMAPTbits(psidByte, 7, ipv4BitIndexLen); + *psidValue = WanManager_GetMAPTbits(psidByte, 7 - ipv4BitIndexLen, psidBitIndexLen); + } +#ifdef FEATURE_MAPT_DEBUG + LOG_PRINT_MAPT("ivictl:psidByte:%d", psidByte); +#endif + return ret; +} + +static int WanManager_ConfigureIpv6Sysevents(char *pdIPv6Prefix, char *ipAddressString, int psidValue) +{ + int ret = RETURN_OK; + struct in6_addr in6Addr; + unsigned char ipAddressBytes[BUFLEN_4]; + struct in_addr result; + unsigned int ipValue = 0; + + inet_pton(AF_INET, ipAddressString, &(result)); + + ipValue = htonl(result.s_addr); + + ipAddressBytes[0] = ipValue & 0xFF; + ipAddressBytes[1] = (ipValue >> 8) & 0xFF; + ipAddressBytes[2] = (ipValue >> 16) & 0xFF; + ipAddressBytes[3] = (ipValue >> 24) & 0xFF; + + if (inet_pton(AF_INET6, pdIPv6Prefix, &in6Addr) <= 0) + { + CcspTraceError(("Invalid ipv6 address=%s", pdIPv6Prefix)); + ret = RETURN_ERR; + return ret; + } + + snprintf(ipv6AddressString, sizeof(ipv6AddressString), "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x", in6Addr.s6_addr[0], in6Addr.s6_addr[1], in6Addr.s6_addr[2], in6Addr.s6_addr[3], in6Addr.s6_addr[4], in6Addr.s6_addr[5], in6Addr.s6_addr[6], in6Addr.s6_addr[7], 0x0, 0x0, ipAddressBytes[3], ipAddressBytes[2], ipAddressBytes[1], ipAddressBytes[0], 0x0, psidValue); + + return ret; +} + +int WanManager_ResetMAPTConfiguration(const char *baseIf, const char *vlanIf) +{ + char cmdConfigureMTUSize[BUFLEN_64] = ""; + int ret = RETURN_OK; + + /* RM16042: Since we have configures MTU size to 1520 for the MAPT functionality, + * we need to reconfigure it back to 1500 when we reset from MAPT configuration. + * Reconfigure eth3 mtu size to 1500. */ + snprintf(cmdConfigureMTUSize, sizeof(cmdConfigureMTUSize), "ip link set dev %s mtu %d ", baseIf, MTU_DEFAULT_SIZE); + +#ifdef FEATURE_MAPT_DEBUG + LOG_PRINT_MAPT("ivictl:cmdConfigureMTUSize:%s", cmdConfigureMTUSize); +#endif + + if ((ret = WanManager_DoSystemActionWithStatus("ivictl", cmdConfigureMTUSize)) < RETURN_OK) + { + CcspTraceError(("Failed to run: %s:%d", cmdConfigureMTUSize, ret)); + return ret; + } + + /* ReConfigure erouter0 MTU size to 1500 */ + snprintf(cmdConfigureMTUSize, sizeof(cmdConfigureMTUSize), "ip link set dev %s mtu %d ", vlanIf, MTU_DEFAULT_SIZE); + +#ifdef FEATURE_MAPT_DEBUG + LOG_PRINT_MAPT("ivictl:cmdConfigureMTUSize:%s", cmdConfigureMTUSize); +#endif + + if ((ret = WanManager_DoSystemActionWithStatus("ivictl", cmdConfigureMTUSize)) < RETURN_OK) + { + CcspTraceError(("Failed to run: %s:%d", cmdConfigureMTUSize, ret)); + return ret; + } + + /* Reset MAPT configuration. + * All the firewall rules should remove once this called. + * To do this we have reset the value for sysevent field + * `mapt_configure_flag` and restart the firewall. */ + //Reset MAP sysevent parameters + maptInfo_reset(); + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_FIREWALL_RESTART, NULL, 0); + CcspTraceNotice(("FEATURE_MAPT: MAP-T configuration cleared\n")); + return RETURN_OK; +} + +#ifdef FEATURE_MAPT_DEBUG +void logPrintMapt(char *fmt,...) +{ + static FILE *fpMaptLogFile; + static char strMaptLogFileName[BUFLEN_32] = "/tmp/log_mapt.txt"; + va_list list; + char *p, *r; + int e; + time_t ctime; + struct tm *info; + + fpMaptLogFile = fopen(strMaptLogFileName, "a"); + + time(&ctime); /* Get current time */ + info = localtime(&ctime); + + fprintf(fpMaptLogFile,"[%02d:%02d:%02d] ", + info->tm_hour,info->tm_min,info->tm_sec); + + va_start(list, fmt); + + for (p = fmt; *p; ++p) + { + if (*p != '%') + { + fputc(*p, fpMaptLogFile); + } + else + { + switch (*++p) + { + + case 's': + { + r = va_arg(list, char *); + + fprintf(fpMaptLogFile, "%s", r); + continue; + } + + case 'd': + { + e = va_arg(list, int); + + fprintf(fpMaptLogFile, "%d", e); + continue; + } + + default: + fputc(*p, fpMaptLogFile); + } + } + } + va_end(list); + fputc('\n', fpMaptLogFile); + fclose(fpMaptLogFile); +} + +void WanManager_UpdateMaptLogFile(Dhcp6cMAPTParametersMsgBody *dhcp6cMAPTMsgBody) +{ + + LOG_PRINT_MAPT("############MAP-T Options DHCP - START#######################"); + LOG_PRINT_MAPT("ruleIPv6Prefix:%s", dhcp6cMAPTMsgBody->ruleIPv6Prefix); + LOG_PRINT_MAPT("ruleIPv4Prefix:%s", dhcp6cMAPTMsgBody->ruleIPv4Prefix); + LOG_PRINT_MAPT("brIPv6Prefix:%s", dhcp6cMAPTMsgBody->brIPv6Prefix); + LOG_PRINT_MAPT("pdIPv6Prefix:%s", dhcp6cMAPTMsgBody->pdIPv6Prefix); + LOG_PRINT_MAPT("iapdPrefixLen:%d", dhcp6cMAPTMsgBody->iapdPrefixLen); + LOG_PRINT_MAPT("psidOffset:%d", dhcp6cMAPTMsgBody->psidOffset); + LOG_PRINT_MAPT("psidLen:%d", dhcp6cMAPTMsgBody->psidLen); + LOG_PRINT_MAPT("psid:%d", dhcp6cMAPTMsgBody->psid); + LOG_PRINT_MAPT("ratio:%d", dhcp6cMAPTMsgBody->ratio); + LOG_PRINT_MAPT("v4Len:%d", dhcp6cMAPTMsgBody->v4Len); + LOG_PRINT_MAPT("v6Len:%d", dhcp6cMAPTMsgBody->v6Len); + LOG_PRINT_MAPT("eaLen:%d", dhcp6cMAPTMsgBody->eaLen); + LOG_PRINT_MAPT("############MAP-T Options DHCP - END#########################"); + + CcspTraceInfo(("SKYWANMGR:MAP-T_OPTIONS:%s,%s,%s,%s,%d,%d,%d,%d,%d,%d,%d,%d", + dhcp6cMAPTMsgBody->ruleIPv6Prefix, + dhcp6cMAPTMsgBody->ruleIPv4Prefix, + dhcp6cMAPTMsgBody->brIPv6Prefix, + dhcp6cMAPTMsgBody->pdIPv6Prefix, + dhcp6cMAPTMsgBody->iapdPrefixLen, + dhcp6cMAPTMsgBody->psidOffset, + dhcp6cMAPTMsgBody->psidLen, + dhcp6cMAPTMsgBody->psid, + dhcp6cMAPTMsgBody->ratio, + dhcp6cMAPTMsgBody->v4Len, + dhcp6cMAPTMsgBody->v6Len, + dhcp6cMAPTMsgBody->eaLen)); +} +#endif /* FEATURE_MAPT_DEBUG */ + +#endif /* FEATURE_MAPT */ + +static int IsValidDnsServer(int32_t af, const char *nameServer) +{ + if (nameServer == NULL) + { + CcspTraceError(("%s %d - invalid argument \n",__FUNCTION__,__LINE__)); + return ANSC_STATUS_FAILURE; + } + + if(af == AF_INET) + { + if(!(IsValidIpv4Address(nameServer))) + { + CcspTraceError(("%s %d - invalid nameserver: %s \n",__FUNCTION__,__LINE__, nameServer)); + return RETURN_ERR; + } + if(IsZeroIpvxAddress(AF_SELECT_IPV4,nameServer)) + { + CcspTraceError(("%s %d - invalid nameserver: %s \n",__FUNCTION__,__LINE__, nameServer)); + return RETURN_ERR; + } + if(!(strncmp(BROADCAST_IP, nameServer, strlen(BROADCAST_IP)))) + { + CcspTraceError(("%s %d - invalid nameserver: %s \n",__FUNCTION__,__LINE__, nameServer)); + return RETURN_ERR; + } + if(!(strncmp(LINKLOCAL_RANGE, nameServer, strlen(LINKLOCAL_RANGE)))) + { + CcspTraceError(("%s %d - invalid nameserver: %s \n",__FUNCTION__,__LINE__, nameServer)); + return RETURN_ERR; + } + if(!(strncmp(LOOPBACK_RANGE, nameServer, strlen(LOOPBACK_RANGE)))) + { + CcspTraceError(("%s %d - invalid nameserver: %s \n",__FUNCTION__,__LINE__, nameServer)); + return RETURN_ERR; + } + } + else + { + if(!(IsValidIpAddress(af, nameServer))) + { + CcspTraceError(("%s %d - invalid nameserver: %s \n",__FUNCTION__,__LINE__, nameServer)); + return RETURN_ERR; + } + if(IsZeroIpvxAddress(AF_SELECT_IPV6, nameServer)) + { + CcspTraceError(("%s %d - invalid nameserver: %s \n",__FUNCTION__,__LINE__, nameServer)); + return RETURN_ERR; + } + } + return RETURN_OK; +} + +int WanManager_CreateResolvCfg(const DnsData_t *dnsInfo) +{ + FILE *fp = NULL; + char cmd[BUFLEN_128]={0}; + int ret = RETURN_OK; + bool valid_dns = FALSE; + if(NULL == dnsInfo) + { + return ANSC_STATUS_FAILURE; + } + CcspTraceInfo(("%s %d -adding nameservers: %s %s %s %s\n", __FUNCTION__,__LINE__,dnsInfo->dns_ipv4_1, dnsInfo->dns_ipv4_2, dnsInfo->dns_ipv6_1, dnsInfo->dns_ipv6_2)); + /* sets nameserver entries to resolv.conf file */ + if((fp = fopen(RESOLV_CONF_FILE, "w+")) == NULL) + { + CcspTraceInfo(("%s %d - Open %s error!\n", __FUNCTION__, __LINE__, RESOLV_CONF_FILE)); + ret = RETURN_ERR; + } + else + { + if(RETURN_OK == IsValidDnsServer(AF_INET, dnsInfo->dns_ipv4_1)) + { + fprintf(fp, "nameserver %s\n", dnsInfo->dns_ipv4_1); + valid_dns = TRUE; + } + if(RETURN_OK == IsValidDnsServer(AF_INET, dnsInfo->dns_ipv4_2)) + { + fprintf(fp, "nameserver %s\n", dnsInfo->dns_ipv4_2); + valid_dns = TRUE; + } + if(RETURN_OK == IsValidDnsServer(AF_INET6, dnsInfo->dns_ipv6_1)) + { + fprintf(fp, "nameserver %s\n", dnsInfo->dns_ipv6_1); + valid_dns = TRUE; + } + if(RETURN_OK == IsValidDnsServer(AF_INET6, dnsInfo->dns_ipv6_2)) + { + fprintf(fp, "nameserver %s\n", dnsInfo->dns_ipv6_2); + valid_dns = TRUE; + } + if (valid_dns == FALSE) + { + CcspTraceInfo(("%s %d - No valid nameserver is available, adding loopback address for nameserver\n", __FUNCTION__,__LINE__)); + fprintf(fp, "nameserver %s \n", LOOPBACK); + } + fclose(fp); + CcspTraceInfo(("%s %d - Active domainname servers set!\n", __FUNCTION__,__LINE__)); + } + return ret; +} + +int WanManager_GetBCastFromIpSubnetMask(const char* inIpStr, const char* inSubnetMaskStr, char *outBcastStr) +{ + struct in_addr ip; + struct in_addr subnetMask; + struct in_addr bCast; + int ret = RETURN_OK; + + if (inIpStr == NULL || inSubnetMaskStr == NULL || outBcastStr == NULL) + { + return RETURN_ERR; + } + + ip.s_addr = inet_addr(inIpStr); + subnetMask.s_addr = inet_addr(inSubnetMaskStr); + bCast.s_addr = ip.s_addr | ~subnetMask.s_addr; + strcpy(outBcastStr, inet_ntoa(bCast)); + + return ret; +} + +int WanManager_AddDefaultGatewayRoute(const WANMGR_IPV4_DATA* pIpv4Info) +{ + char cmd[BUFLEN_128]={0}; + int ret = RETURN_OK; + FILE *fp = NULL; + + /* delete default gateway first before add */ + snprintf(cmd, sizeof(cmd), "route del default 2>/dev/null"); + WanManager_DoSystemAction("SetUpDefaultSystemGateway:", cmd); + + /* Sets default gateway route entry */ + /* For IPoE, always use gw IP address. */ + if (IsValidIpv4Address(pIpv4Info->gateway) && !(IsZeroIpvxAddress(AF_SELECT_IPV4, pIpv4Info->gateway))) + { + snprintf(cmd, sizeof(cmd), "route add default gw %s dev %s", pIpv4Info->gateway, pIpv4Info->ifname); + WanManager_DoSystemAction("SetUpDefaultSystemGateway:", cmd); + CcspTraceInfo(("%s %d - The default gateway route entries set!\n",__FUNCTION__,__LINE__)); + } + + return ret; +} + +static BOOL IsValidIpv4Address(const char* input) +{ + BOOL ret = TRUE; + char *pToken = NULL; + char *pLast = NULL; + char buf[BUFLEN_16]; + uint32_t i, num; + + if (input == NULL || strlen(input) < 7 || strlen(input) > 15) + { + return FALSE; + } + + /* need to copy since strtok_r updates string */ + strcpy(buf, input); + + /* IP address has the following format + xxx.xxx.xxx.xxx where x is decimal number */ + pToken = strtok_r(buf, ".", &pLast); + num = strtoul(pToken, NULL, 10); + if (num > 255) + { + ret = FALSE; + } + else + { + for ( i = 0; i < 3; i++ ) + { + pToken = strtok_r(NULL, ".", &pLast); + + num = strtoul(pToken, NULL, 10); + if (num > 255) + { + ret = FALSE; + break; + } + } + } + + return ret; +} + +static BOOL IsZeroIpvxAddress(uint32_t ipvx, const char *addr) +{ + if (IS_EMPTY_STR(addr)) + { + return TRUE; + } + + /* + * Technically, the ::/0 is not an all zero address, but it is used by our + * routing code to specify the default route. See Wikipedia IPv6_address + */ + if (((ipvx & AF_SELECT_IPV4) && !strcmp(addr, "0.0.0.0")) || + ((ipvx & AF_SELECT_IPV6) && + (!strcmp(addr, "0:0:0:0:0:0:0:0") || + !strcmp(addr, "::") || + !strcmp(addr, "::/128") || + !strcmp(addr, "::/0"))) ) + { + return TRUE; + } + + return FALSE; +} + +static BOOL IsValidIpAddress(int32_t af, const char* address) +{ + if ( IS_EMPTY_STRING(address) ) return FALSE; + if (af == AF_INET6) + { + struct in6_addr in6Addr; + uint32_t plen; + char addr[IP_ADDR_LENGTH]; + + if (ParsePrefixAddress(address, addr, &plen) != ANSC_STATUS_SUCCESS) + { + CcspTraceInfo(("Invalid ipv6 address=%s", address)); + return FALSE; + } + + if (inet_pton(AF_INET6, addr, &in6Addr) <= 0) + { + CcspTraceInfo(("Invalid ipv6 address=%s", address)); + return FALSE; + } + + return TRUE; + } + else + { + if (af == AF_INET) + { + return IsValidIpv4Address(address); + } + else + { + return FALSE; + } + } +} + +static int ParsePrefixAddress(const char *prefixAddr, char *address, uint32_t *plen) +{ + int ret = RETURN_OK; + char *tmpBuf; + char *separator; + uint32_t len; + + if (prefixAddr == NULL || address == NULL || plen == NULL) + { + return RETURN_ERR; + } + + *address = '\0'; + *plen = 128; + + len = strlen(prefixAddr); + + if ((tmpBuf = malloc(len+1)) == NULL) + { + CcspTraceError(("%s %d - alloc of %d bytes failed",__FUNCTION__,__LINE__, len)); + ret = RETURN_ERR; + } + else + { + sprintf(tmpBuf, "%s", prefixAddr); + separator = strchr(tmpBuf, '/'); + if (separator != NULL) + { + /* break the string into two strings */ + *separator = 0; + separator++; + while ((isspace(*separator)) && (*separator != 0)) + { + /* skip white space after comma */ + separator++; + } + + *plen = atoi(separator); + } + + if (strlen(tmpBuf) < BUFLEN_40 && *plen <= 128) + { + strcpy(address, tmpBuf); + } + else + { + ret = RETURN_ERR; + } + free(tmpBuf); + } + + return ret; + +} + +static ANSC_STATUS getIfAddr6(const char *ifname , uint32_t addrIdx, + char *ipAddr, uint32_t *ifIndex, uint32_t *prefixLen, uint32_t *scope, uint32_t *ifaFlags) +{ + int ret = ANSC_STATUS_FAILURE; + FILE *fp; + uint32_t count = 0; + char line[BUFLEN_64]; + + *ipAddr = '\0'; + + if ((fp = fopen("/proc/net/if_inet6", "r")) == NULL) + { + CcspTraceInfo(("failed to open /proc/net/if_inet6")); + return ANSC_STATUS_FAILURE; + } + + while (fgets(line, sizeof(line), fp) != NULL) + { + /* remove the carriage return char */ + line[strlen(line)-1] = '\0'; + + if (strstr(line, ifname) != NULL) + { + char *addr, *ifidx, *plen, *scp, *flags, *devname; + char *nextToken = NULL; + + /* the first token in the line is the ip address */ + addr = strtok_r(line, " ", &nextToken); + + /* the second token is the Netlink device number (interface index) in hexadecimal */ + ifidx = strtok_r(NULL, " ", &nextToken); + if (ifidx == NULL) + { + CcspTraceInfo(("Invalid /proc/net/if_inet6 line")); + ret = ANSC_STATUS_FAILURE; + break; + } + + /* the third token is the Prefix length in hexadecimal */ + plen = strtok_r(NULL, " ", &nextToken); + if (plen == NULL) + { + CcspTraceInfo(("Invalid /proc/net/if_inet6 line")); + ret = ANSC_STATUS_FAILURE; + break; + } + + /* the forth token is the Scope value */ + scp = strtok_r(NULL, " ", &nextToken); + if (scp == NULL) + { + CcspTraceInfo(("Invalid /proc/net/if_inet6 line")); + ret = ANSC_STATUS_FAILURE; + break; + } + + /* the fifth token is the ifa flags */ + flags = strtok_r(NULL, " ", &nextToken); + if (flags == NULL) + { + CcspTraceInfo(("Invalid /proc/net/if_inet6 line")); + ret = ANSC_STATUS_FAILURE; + break; + } + + /* the sixth token is the device name */ + devname = strtok_r(NULL, " ", &nextToken); + if (devname == NULL) + { + CcspTraceInfo(("Invalid /proc/net/if_inet6 line")); + ret = ANSC_STATUS_FAILURE; + break; + } + else + { + if (strcmp(devname, ifname) != 0) + { + continue; + } + else if (count == addrIdx) + { + int32_t i; + char *p1, *p2; + + *ifIndex = strtoul(ifidx, NULL, 16); + *prefixLen = strtoul(plen, NULL, 16); + *scope = strtoul(scp, NULL, 16); + *ifaFlags = strtoul(flags, NULL, 16); + + /* insert a colon every 4 digits in the address string */ + p2 = ipAddr; + for (i = 0, p1 = addr; *p1 != '\0'; i++) + { + if (i == 4) + { + i = 0; + *p2++ = ':'; + } + *p2++ = *p1++; + } + *p2 = '\0'; + + ret = ANSC_STATUS_SUCCESS; + break; /* done */ + } + else + { + count++; + } + } + } + } /* while */ + + fclose(fp); + + return ret; + +} /* End of getIfAddr6() */ + +ANSC_STATUS WanManager_getGloballyUniqueIfAddr6(const char *ifname, char *ipAddr, uint32_t *prefixLen) +{ + uint32_t addrIdx=0; + uint32_t netlinkIndex=0; + uint32_t scope=0; + uint32_t ifaflags=0; + int ret= ANSC_STATUS_SUCCESS; + + while (ANSC_STATUS_SUCCESS == ret) + { + ret = getIfAddr6(ifname, addrIdx, ipAddr, &netlinkIndex, + prefixLen, &scope, &ifaflags); + if ((ANSC_STATUS_SUCCESS == ret) && (0 == scope)) // found it + return ANSC_STATUS_SUCCESS; + + addrIdx++; + } + + return ANSC_STATUS_FAILURE; +} + + +#ifdef FEATURE_802_1P_COS_MARKING + +ANSC_HANDLE WanManager_AddIfaceMarking(DML_WAN_IFACE* pWanDmlIface, ULONG* pInsNumber) +{ + DATAMODEL_MARKING* pDmlMarking = (DATAMODEL_MARKING*) &(pWanDmlIface->Marking); + DML_MARKING* p_Marking = NULL; + CONTEXT_MARKING_LINK_OBJECT* pMarkingCxtLink = NULL; + + //Verify limit of the marking table + if( WAN_IF_MARKING_MAX_LIMIT < pDmlMarking->ulNextInstanceNumber ) + { + CcspTraceError(("%s %d - Failed to add Marking entry due to maximum limit(%d)\n",__FUNCTION__,__LINE__,WAN_IF_MARKING_MAX_LIMIT)); + return NULL; + } + + p_Marking = (DML_MARKING*)AnscAllocateMemory(sizeof(DML_MARKING)); + pMarkingCxtLink = (CONTEXT_MARKING_LINK_OBJECT*)AnscAllocateMemory(sizeof(CONTEXT_MARKING_LINK_OBJECT)); + if((p_Marking == NULL) || (pMarkingCxtLink == NULL)) + { + if( NULL != pMarkingCxtLink ) + { + AnscFreeMemory(pMarkingCxtLink); + pMarkingCxtLink = NULL; + } + + if( NULL != p_Marking ) + { + AnscFreeMemory(p_Marking); + p_Marking = NULL; + } + return NULL; + } + + + /* now we have this link content */ + pMarkingCxtLink->hContext = (ANSC_HANDLE)p_Marking; + pMarkingCxtLink->bNew = TRUE; + + pMarkingCxtLink->InstanceNumber = pDmlMarking->ulNextInstanceNumber; + *pInsNumber = pDmlMarking->ulNextInstanceNumber; + + //Assign actual instance number + p_Marking->InstanceNumber = pDmlMarking->ulNextInstanceNumber; + + pDmlMarking->ulNextInstanceNumber++; + + //Assign WAN interface instance for reference + p_Marking->ulWANIfInstanceNumber = pWanDmlIface->uiInstanceNumber; + + //Initialise all marking members + memset( p_Marking->Alias, 0, sizeof( p_Marking->Alias ) ); + p_Marking->SKBPort = 0; + p_Marking->SKBMark = 0; + p_Marking->EthernetPriorityMark = -1; + + SListPushMarkingEntryByInsNum(&pDmlMarking->MarkingList, (PCONTEXT_LINK_OBJECT)pMarkingCxtLink); + + return (ANSC_HANDLE)pMarkingCxtLink; +} + + +#endif /* * FEATURE_802_1P_COS_MARKING */ + +ANSC_STATUS WanManager_CreatePPPSession(DML_WAN_IFACE* pInterface) +{ + pthread_t pppThreadId; + INT iErrorCode; + char wan_iface_name[10] = {0}; + + syscfg_init(); + /* Generate client-duid file for dibbler */ + generate_client_duid_conf(); + + /* Remove erouter0 dummy wan bridge if exists */ + deleteDummyWanBridgeIfExist(); + if (pInterface->PPP.LinkType == WAN_IFACE_PPP_LINK_TYPE_PPPoA) + { + strncpy(wan_iface_name, BASE_IFNAME_PPPoA, strlen(BASE_IFNAME_PPPoA)); + } + else if (pInterface->PPP.LinkType == WAN_IFACE_PPP_LINK_TYPE_PPPoE) + { + strncpy(wan_iface_name, BASE_IFNAME_PPPoE, strlen(BASE_IFNAME_PPPoE)); + } + else + { + strncpy(wan_iface_name, DEFAULT_IFNAME, strlen(DEFAULT_IFNAME)); + } + if (syscfg_set(NULL, SYSCFG_WAN_INTERFACE_NAME, wan_iface_name) != 0) + { + CcspTraceError(("%s %d - syscfg_set failed to set Interafce=%s \n", __FUNCTION__, __LINE__, wan_iface_name )); + }else{ + CcspTraceInfo(("%s %d - syscfg_set successfully to set Interafce=%s \n", __FUNCTION__, __LINE__, wan_iface_name )); + } + syscfg_commit(); + iErrorCode = pthread_create( &pppThreadId, NULL, &DmlHandlePPPCreateRequestThread, (void*)pInterface ); + if( 0 != iErrorCode ) + { + CcspTraceInfo(("%s %d - Failed to start VLAN refresh thread EC:%d\n", __FUNCTION__, __LINE__, iErrorCode )); + return ANSC_STATUS_FAILURE; + } + return ANSC_STATUS_SUCCESS; +} + +static void* DmlHandlePPPCreateRequestThread( void *arg ) +{ + char acSetParamName[DATAMODEL_PARAM_LENGTH] = {0}; + char acSetParamValue[DATAMODEL_PARAM_LENGTH] = {0}; + char adslPassword[DATAMODEL_PARAM_LENGTH] = {0}; + char adslUserName[DATAMODEL_PARAM_LENGTH] = {0}; + INT iPPPInstance = -1; + + DML_WAN_IFACE* pInterface = (char *) arg; + + if( NULL == pInterface ) + { + CcspTraceError(("%s Invalid Memory\n", __FUNCTION__)); + return ANSC_STATUS_FAILURE; + } + + pthread_detach(pthread_self()); + + //Create PPP Interface + if( -1 == iPPPInstance ) + { + char acTableName[ 128 ] = { 0 }; + INT iNewTableInstance = -1; + + sprintf( acTableName, "%s", PPP_INTERFACE_TABLE ); + if ( CCSP_SUCCESS != CcspBaseIf_AddTblRow ( + bus_handle, + PPPMGR_COMPONENT_NAME, + PPPMGR_DBUS_PATH, + 0, /* session id */ + acTableName, + &iNewTableInstance + ) ) + { + CcspTraceError(("%s Failed to add table %s\n", __FUNCTION__,acTableName)); + return ANSC_STATUS_FAILURE; + } + + //Assign new instance + iPPPInstance = iNewTableInstance; + } + + CcspTraceInfo(("%s %d PPP Interface Instance:%d\n",__FUNCTION__, __LINE__, iPPPInstance)); + + //Set Lower Layer + snprintf( acSetParamName, DATAMODEL_PARAM_LENGTH, PPP_INTERFACE_LOWERLAYERS, iPPPInstance ); + snprintf( acSetParamValue, DATAMODEL_PARAM_LENGTH, "%s", pInterface->Phy.Path ); + WanMgr_RdkBus_SetParamValues( PPPMGR_COMPONENT_NAME, PPPMGR_DBUS_PATH, acSetParamName, acSetParamValue, ccsp_string, FALSE ); + + //Set Alias + snprintf( acSetParamName, DATAMODEL_PARAM_LENGTH, PPP_INTERFACE_ALIAS, iPPPInstance ); + snprintf( acSetParamValue, DATAMODEL_PARAM_LENGTH, "%s", pInterface->Wan.Name ); + WanMgr_RdkBus_SetParamValues( PPPMGR_COMPONENT_NAME, PPPMGR_DBUS_PATH, acSetParamName, acSetParamValue, ccsp_string, FALSE ); + + CcspTraceError(("%s Going to call GetAdslUsernameAndPassword \n", __FUNCTION__ )); + +#ifdef _HUB4_PRODUCT_REQ_ + if (GetAdslUsernameAndPassword(adslUserName, adslPassword) != ANSC_STATUS_SUCCESS ) + { + CcspTraceError(("%s Failed to get ADSL username and password \n", __FUNCTION__ )); + } +#endif + CcspTraceError(("%s adslusername = %s adslpassword = %s \n", __FUNCTION__, adslUserName, adslPassword)); + //Set Username + snprintf( acSetParamName, DATAMODEL_PARAM_LENGTH, PPP_INTERFACE_USERNAME, iPPPInstance ); + snprintf( acSetParamValue, DATAMODEL_PARAM_LENGTH, "%s", adslUserName ); + WanMgr_RdkBus_SetParamValues( PPPMGR_COMPONENT_NAME, PPPMGR_DBUS_PATH, acSetParamName, acSetParamValue, ccsp_string, TRUE ); + + //Set Password + snprintf( acSetParamName, DATAMODEL_PARAM_LENGTH, PPP_INTERFACE_PASSWORD, iPPPInstance ); + snprintf( acSetParamValue, DATAMODEL_PARAM_LENGTH, "%s", adslPassword ); + WanMgr_RdkBus_SetParamValues( PPPMGR_COMPONENT_NAME, PPPMGR_DBUS_PATH, acSetParamName, acSetParamValue, ccsp_string, TRUE ); + + //Set IPCPEnable + snprintf( acSetParamName, DATAMODEL_PARAM_LENGTH, PPP_INTERFACE_IPCP_ENABLE, iPPPInstance ); + if (pInterface->PPP.IPCPEnable == TRUE) + { + snprintf( acSetParamValue, DATAMODEL_PARAM_LENGTH, "%s", "true" ); + } + else + { + snprintf( acSetParamValue, DATAMODEL_PARAM_LENGTH, "%s", "false" ); + } + WanMgr_RdkBus_SetParamValues( PPPMGR_COMPONENT_NAME, PPPMGR_DBUS_PATH, acSetParamName, acSetParamValue, ccsp_boolean, TRUE ); + + //Set IPv6CPEnable + snprintf( acSetParamName, DATAMODEL_PARAM_LENGTH, PPP_INTERFACE_IPV6CP_ENABLE, iPPPInstance ); + if (pInterface->PPP.IPV6CPEnable == TRUE) + { + snprintf( acSetParamValue, DATAMODEL_PARAM_LENGTH, "%s", "true" ); + } + else + { + snprintf( acSetParamValue, DATAMODEL_PARAM_LENGTH, "%s", "false" ); + } + WanMgr_RdkBus_SetParamValues( PPPMGR_COMPONENT_NAME, PPPMGR_DBUS_PATH, acSetParamName, acSetParamValue, ccsp_boolean, TRUE ); + + //Set LinkType + snprintf( acSetParamName, DATAMODEL_PARAM_LENGTH, PPP_INTERFACE_LINKTYPE, iPPPInstance ); + if (pInterface->PPP.LinkType == WAN_IFACE_PPP_LINK_TYPE_PPPoA) + { + snprintf( acSetParamValue, DATAMODEL_PARAM_LENGTH, "%s", "PPPoA" ); + } + else if (pInterface->PPP.LinkType == WAN_IFACE_PPP_LINK_TYPE_PPPoE) + { + snprintf( acSetParamValue, DATAMODEL_PARAM_LENGTH, "%s", "PPPoE" ); + } + WanMgr_RdkBus_SetParamValues( PPPMGR_COMPONENT_NAME, PPPMGR_DBUS_PATH, acSetParamName, acSetParamValue, ccsp_string, TRUE ); + + //Set PPP Enable + snprintf( acSetParamName, DATAMODEL_PARAM_LENGTH, PPP_INTERFACE_ENABLE, iPPPInstance ); + if (pInterface->PPP.Enable == TRUE) + { + snprintf( acSetParamValue, DATAMODEL_PARAM_LENGTH, "%s", "true" ); + } + else + { + snprintf( acSetParamValue, DATAMODEL_PARAM_LENGTH, "%s", "false" ); + } + WanMgr_RdkBus_SetParamValues( PPPMGR_COMPONENT_NAME, PPPMGR_DBUS_PATH, acSetParamName, acSetParamValue, ccsp_boolean, TRUE ); + + snprintf( acSetParamValue, DATAMODEL_PARAM_LENGTH, "%s%d.", PPP_INTERFACE_TABLE, iPPPInstance); + CcspTraceInfo(("%s %d Set ppp path to %s \n", __FUNCTION__,__LINE__ ,acSetParamValue )); + strcpy(pInterface->PPP.Path, acSetParamValue); + + CcspTraceInfo(("%s %d Successfully created PPP %s interface \n", __FUNCTION__,__LINE__, pInterface->Wan.Name )); + + //Clean exit + pthread_exit(NULL); + + return NULL; +} + +ANSC_STATUS WanManager_DeletePPPSession(DML_WAN_IFACE* pInterface) +{ + char acSetParamName[256] = {0}; + char acSetParamValue[256] = {0}; + INT iPPPInstance = -1; + + if( NULL == pInterface ) + { + CcspTraceError(("%s Invalid Memory\n", __FUNCTION__)); + return ANSC_STATUS_FAILURE; + } + syscfg_init(); + memset( acSetParamName, 0, DATAMODEL_PARAM_LENGTH ); + memset( acSetParamValue, 0, DATAMODEL_PARAM_LENGTH ); + + iPPPInstance = get_index_from_path(pInterface->PPP.Path); + if (iPPPInstance == -1) + { + CcspTraceInfo(("%s %d PPP path is invalid \n",__FUNCTION__, __LINE__)); + return ANSC_STATUS_FAILURE; + } + + //Set PPP Enable + snprintf( acSetParamName, DATAMODEL_PARAM_LENGTH, PPP_INTERFACE_ENABLE, iPPPInstance ); + snprintf( acSetParamValue, DATAMODEL_PARAM_LENGTH, "%s", "false" ); + WanMgr_RdkBus_SetParamValues( PPPMGR_COMPONENT_NAME, PPPMGR_DBUS_PATH, acSetParamName, acSetParamValue, ccsp_boolean, TRUE ); + + //Delete PPP Instance + snprintf( acSetParamName, DATAMODEL_PARAM_LENGTH, PPP_INTERFACE_TABLE, iPPPInstance ); + if ( CCSP_SUCCESS != CcspBaseIf_DeleteTblRow ( + bus_handle, + PPPMGR_COMPONENT_NAME, + PPPMGR_DBUS_PATH, + 0, /* session id */ + acSetParamName)) + { + CcspTraceError(("%s Failed to delete table %s\n", __FUNCTION__, acSetParamName)); + return ANSC_STATUS_FAILURE; + } + + CcspTraceInfo(("%s %d Successfully created PPP interface \n", __FUNCTION__,__LINE__ )); + + sleep(2); + + /* Create a dummy wan bridge */ + if (syscfg_set(NULL, SYSCFG_WAN_INTERFACE_NAME, DEFAULT_IFNAME) != 0) + { + CcspTraceError(("%s %d - syscfg_set failed to set Interafce=%s \n", __FUNCTION__, __LINE__, DEFAULT_IFNAME )); + }else{ + CcspTraceInfo(("%s %d - syscfg_set successfully to set Interafce=%s \n", __FUNCTION__, __LINE__, DEFAULT_IFNAME )); + } + syscfg_commit(); + createDummyWanBridge(); + + return ANSC_STATUS_SUCCESS; +} + +int WanManager_AddGatewayRoute(const WANMGR_IPV4_DATA* pIpv4Info) +{ + char cmd[BUFLEN_128]={0}; + int ret = RETURN_OK; + FILE *fp = NULL; + + /* delete gateway first before add */ + snprintf(cmd, sizeof(cmd), "route del %s dev %s", pIpv4Info->gateway, pIpv4Info->ifname); + WanManager_DoSystemAction("SetUpSystemGateway:", cmd); + + /* Sets gateway route entry */ + if (IsValidIpv4Address(pIpv4Info->gateway) && !(IsZeroIpvxAddress(AF_SELECT_IPV4, pIpv4Info->gateway))) + { + snprintf(cmd, sizeof(cmd), "ip route add %s dev %s", pIpv4Info->gateway, pIpv4Info->ifname); + WanManager_DoSystemAction("SetUpSystemGateway:", cmd); + CcspTraceInfo(("%s %d - The gateway route entries set!\n",__FUNCTION__,__LINE__)); + } + + return ret; +} + +static int get_index_from_path(const char *path) +{ + int index = -1; + + if(path == NULL) + { + return -1; + } + + sscanf(path, "%*[^0-9]%d", &index); + return index; +} + +#ifdef _HUB4_PRODUCT_REQ_ +static ANSC_STATUS GetAdslUsernameAndPassword(char *Username, char *Password) +{ + int ret= ANSC_STATUS_SUCCESS; + FILE *fp = NULL; + char line[BUFLEN_128] = {0}; + + if (Username == NULL || Password == NULL) + { + return ANSC_STATUS_FAILURE; + } + if (fp = fopen(SERIALIZATION_DATA, "r")) + { + while(fgets(line, sizeof(line), fp)!=NULL) + { + if(strstr(line,"ADSLUSER")) + { + char * ch = strrchr(line,'='); + strncpy(Username, ch+1, BUFLEN_64); + Username[strcspn(Username, "\n\r")] = 0; + } + if(strstr(line,"ADSLPASS")) + { + char * ch = strrchr(line,'='); + strncpy(Password, ch+1, BUFLEN_64); + Password[strcspn(Password, "\n\r")] = 0; + } + } + if(fp != NULL) + { + fclose(fp); + fp = NULL; + } + } + else + { + ret = ANSC_STATUS_FAILURE; + } + + return ret; +} +#endif + +static void generate_client_duid_conf() +{ + char duid[256] = {0}; + char file_path[64] = {0}; + char wan_mac[64] = {0}; + + FILE *fp_duid = NULL; + FILE *fp_mac_addr_table = NULL; + + fp_duid = fopen(DUID_CLIENT, "r"); + + if( fp_duid == NULL ) + { + sprintf(file_path, "/sys/class/net/%s/address", PHY_WAN_IF_NAME); + fp_mac_addr_table = fopen(file_path, "r"); + if(fp_mac_addr_table == NULL) + { + CcspTraceError(("Failed to open mac address table")); + } + else + { + fread(wan_mac, sizeof(wan_mac),1, fp_mac_addr_table); + fclose(fp_mac_addr_table); + } + + fp_duid = fopen(DUID_CLIENT, "w"); + + if(fp_duid) + { + sprintf(duid, DUID_TYPE); + sprintf(duid+6, HW_TYPE); + sprintf(duid+12, wan_mac); + + fprintf(fp_duid, "%s", duid); + fclose(fp_duid); + } + } + else + { + fclose(fp_duid); + CcspTraceError(("dibbler client-duid file exist")); + } + + return; +} + +static void createDummyWanBridge() +{ + char syscmd[256] = {'\0'}; + char wan_mac[64] = {'\0'}; + char file_path[64] = {0}; + FILE *fp_mac_addr_table = NULL; + + sprintf(file_path, "/sys/class/net/%s/address", PHY_WAN_IF_NAME); + fp_mac_addr_table = fopen(file_path, "r"); + if(fp_mac_addr_table == NULL) + { + CcspTraceError(("Failed to open mac address table")); + } + else + { + fread(wan_mac, sizeof(wan_mac),1, fp_mac_addr_table); + fclose(fp_mac_addr_table); + } + + memset(syscmd, '\0', sizeof(syscmd)); + snprintf(syscmd, sizeof(syscmd), "brctl addbr %s", PHY_WAN_IF_NAME); + system(syscmd); + + memset(syscmd, '\0', sizeof(syscmd)); + snprintf(syscmd, sizeof(syscmd), "ip link set dev %s address %s", PHY_WAN_IF_NAME, wan_mac); + system(syscmd); + + return; +} + +static void deleteDummyWanBridgeIfExist() +{ + char syscmd[256] = {'\0'}; + char resultBuff[256] = {'\0'}; + char cmd[256] = {'\0'}; + FILE *fp = NULL; + + memset(resultBuff, '\0', sizeof(resultBuff)); + memset(cmd, '\0', sizeof(cmd)); + memset(syscmd, '\0', sizeof(syscmd)); + snprintf(cmd, sizeof(cmd), "ip -d link show %s | tail -n +2 | grep bridge", PHY_WAN_IF_NAME); + fp = popen(cmd, "r"); + if (fp != NULL) + { + fgets(resultBuff, 1024, fp); + if (resultBuff[0] == '\0') + { + // Empty result. No bridge found. + CcspTraceInfo(("%s bridge interface is not exists in the system \n", PHY_WAN_IF_NAME)); + } + else + { + CcspTraceInfo(("%s bridge interface is found in the system, so delete it \n", PHY_WAN_IF_NAME)); + /* Down the interface before we delete it. */ + snprintf(syscmd, sizeof(syscmd), "ifconfig %s down", PHY_WAN_IF_NAME); + system(syscmd); + memset(syscmd, '\0', sizeof(syscmd)); + snprintf(syscmd, sizeof(syscmd), "brctl delbr %s", PHY_WAN_IF_NAME); + system(syscmd); + } + pclose(fp); + } + + return; +} + +ANSC_STATUS WanManager_CheckGivenPriorityExists(INT IfIndex, UINT uiTotalIfaces, INT priority, DML_WAN_IFACE_TYPE priorityType, BOOL *Status) +{ + ANSC_STATUS retStatus = ANSC_STATUS_SUCCESS; + INT uiLoopCount = 0; + INT wan_if_count = 0; + + if ( uiTotalIfaces <= 0 ) + { + CcspTraceError(("%s Invalid Parameter\n", __FUNCTION__ )); + return ANSC_STATUS_FAILURE; + } + + for( uiLoopCount = 0; uiLoopCount < uiTotalIfaces; uiLoopCount++ ) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(uiLoopCount); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanIfaceData = &(pWanDmlIfaceData->data); + if( uiLoopCount == IfIndex ) + { + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + continue; + } + if(pWanIfaceData->Wan.Priority == priority) + { + if ( pWanIfaceData->Wan.Type == priorityType) + { + *Status = TRUE; + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + return retStatus; + } + } + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + + return retStatus; +} + +ANSC_STATUS WanManager_CheckGivenTypeExists(INT IfIndex, UINT uiTotalIfaces, DML_WAN_IFACE_TYPE priorityType, INT priority, BOOL *Status) +{ + ANSC_STATUS retStatus = ANSC_STATUS_SUCCESS; + INT uiLoopCount = 0; + INT wan_if_count = 0; + + if ( uiTotalIfaces <= 0 ) + { + CcspTraceError(("%s Invalid Parameter\n", __FUNCTION__ )); + return ANSC_STATUS_FAILURE; + } + + for( uiLoopCount = 0; uiLoopCount < uiTotalIfaces; uiLoopCount++ ) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(uiLoopCount); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanIfaceData = &(pWanDmlIfaceData->data); + if( uiLoopCount == IfIndex ) + { + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + continue; + } + if(pWanIfaceData->Wan.Type == priorityType) + { + if ( pWanIfaceData->Wan.Priority == priority) + { + *Status = TRUE; + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + return retStatus; + } + } + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + + return retStatus; +} + diff --git a/source/WanManager/wanmgr_net_utils.h b/source/WanManager/wanmgr_net_utils.h new file mode 100644 index 00000000..334610a8 --- /dev/null +++ b/source/WanManager/wanmgr_net_utils.h @@ -0,0 +1,229 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2015 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +#ifndef _WANMGR_NET_UTILS_H_ +#define _WANMGR_NET_UTILS_H_ + +/* ---- Include Files ---------------------------------------- */ +#include +#include +#include "wanmgr_rdkbus_common.h" +#include "ipc_msg.h" +#include "wanmgr_dml.h" +#include "wanmgr_utils.h" +// +// +///* ---- Global Constants -------------------------- */ + +#define DHCPV6_CLIENT_NAME "dibbler-client" +// + + +#define PTM_IFC_STR "ptm" +#define PHY_WAN_IF_NAME "erouter0" +#define ETH_BRIDGE_NAME "brlan0" +#define LAN_BRIDGE_NAME "brlan0" +// + +#define WAN_STATUS_UP "up" +#define WAN_STATUS_DOWN "down" + +#define WAN_IF_MARKING_MAX_LIMIT ( 15 ) +typedef struct _CONTEXT_MARKING_LINK_OBJECT +{ + CONTEXT_LINK_CLASS_CONTENT + BOOL bFound; +} CONTEXT_MARKING_LINK_OBJECT; + + + +#define ACCESS_CONTEXT_MARKING_LINK_OBJECT(p) \ + ACCESS_CONTAINER(p, CONTEXT_MARKING_LINK_OBJECT, Linkage) + + + +#ifdef FEATURE_MAPT_DEBUG +void logPrintMapt(char *fmt,...); +#define LOG_PRINT_MAPT(...) logPrintMapt(__VA_ARGS__ ) +#endif /*FEATURE_MAPT_DEBUG*/ + +typedef struct +{ + char dns_ipv4_1[BUFLEN_64]; + char dns_ipv4_2[BUFLEN_64]; + char dns_ipv6_1[BUFLEN_128]; + char dns_ipv6_2[BUFLEN_128]; +} DnsData_t; + + +typedef enum +{ + DEL_ADDR = 0, + SET_LFT = 1 +} Ipv6OperType; + + +/* ---- Global Variables -------------------------- */ +//extern int sysevent_fd; +//extern token_t sysevent_token; +//extern eRouterRegion_t region; +/* Global structure to hold wan interface data. + * This structure object defined in ipc module and this + * can be also may required in other area. */ +//extern WanData_t gWanData; +//extern pthread_mutex_t gmWanDataMutex; + +/* ---- Global Prototypes -------------------------- */ +/*************************************************************************** + * @brief API used to start Dhcpv6 client application. + * @param pcInterfaceName Interface name on which the dhcpv6 needs to start + * @param isPPP indicates PPP enabled or nor + * @return ANSC_STATUS_SUCCESS upon success else returned error code. + ***************************************************************************/ +ANSC_STATUS WanManager_StartDhcpv6Client(const char *pcInterfaceName, BOOL isPPP); + +/*************************************************************************** + * @brief API used to stop Dhcpv6 client application. + * @param boolDisconnect This indicates whether this function called from + * disconnect context or not + * @return ANSC_STATUS_SUCCESS upon success else returned error code. + ***************************************************************************/ +ANSC_STATUS WanManager_StopDhcpv6Client(BOOL boolDisconnect); + +/*************************************************************************** + * @brief API used to start Dhcpv4 client application. + * @param intf Interface name on which the dhcpv4 needs to start + * @param discover flag indicates discover on interface forced. + * @return ANSC_STATUS_SUCCESS upon success else returned error code. + ***************************************************************************/ +uint32_t WanManager_StartDhcpv4Client(const char* intf, BOOL discover); + +/*************************************************************************** + * @brief API used to stop Dhcpv4 client application. + * @param sendReleaseAndExit flag indicates needs to send release packet before + * exit. + * @return ANSC_STATUS_SUCCESS upon success else returned error code. + ***************************************************************************/ +ANSC_STATUS WanManager_StopDhcpv4Client(BOOL sendReleaseAndExit); + +/*************************************************************************** + * @brief API used to restart Dhcpv6 client application. + * @param ifName_info interface name + * @param dynamicIpEnabled indicates dynamicip needs to be enable + * @param pdEnabled indicates packket delegation enabled + * @return ANSC_STATUS_SUCCESS upon success else returned error code. + ***************************************************************************/ +uint32_t WanManager_RestartDhcp6c(const char *ifName_info, BOOL dynamicIpEnabled, + BOOL pdEnabled, BOOL aftrName); + + + + +/*************************************************************************** + * @brief Utility function used to check Application is running. + * @param appName string indicates application name + * @return status of system() call. + ***************************************************************************/ +BOOL WanManager_IsApplicationRunning(const char* appName); + +/*************************************************************************** + * @brief Utility function used to perform operation on IPV6 addresses + * for a particular interface + * @param ifname string indicates interface name + * @param opr indicates operation type (Delete/Set) + * @param preflft indicates preferred lifetime + * @param vallft indicates valid lifetime + * @return 0 upon success else -1 returned + ***************************************************************************/ +int WanManager_Ipv6AddrUtil(char *ifname,Ipv6OperType opr,int preflft,int vallft); + +#ifdef FEATURE_MAPT +/*********************************************************************************** + * @brief This API used to process mapt configuration data. + * @param dhcp6cMAPTMsgBody Hold the mapt data received from dhcp6 server. + * @param baseIf Base interface name + * @param vlanIf Vlan interface name + * @return RETURN_OK in case of success else error code returned. + ************************************************************************************/ +int WanManager_ProcessMAPTConfiguration(Dhcp6cMAPTParametersMsgBody *dhcp6cMAPTMsgBody, const char *baseIf, const char *vlanIf); +#endif + +/*********************************************************************************** + * @brief This API used to reset mapt configuration data. + * @param baseIf Base interface name + * @param vlanIf Vlan interface name + * @return RETURN_OK in case of success else error code returned. + ************************************************************************************/ +int WanManager_ResetMAPTConfiguration(const char *baseIf, const char *vlanIf); + +/*************************************************************************** + * @brief API used to update /etc/resolv.conf file with dns configuration + * @param dnsInfo pointer to DnsData_t contains the dns info + * @return RETURN_OK upon success else returned error code. + ****************************************************************************/ +int WanManager_CreateResolvCfg(const DnsData_t *dnsInfo); + +/*************************************************************************** + * @brief API used to update default ipv4 gateway + * @param ipv4Info pointer to ipc_dhcpv4_data_t holds the IPv4 configuration + * @return RETURN_OK upon success else returned error code. + ****************************************************************************/ +int WanManager_AddDefaultGatewayRoute(const WANMGR_IPV4_DATA* ipv4Info); + +/*************************************************************************** + * @brief API used to get broadcast IP from IP and subnet mask + * @param inIpStr IP address + * @param inSubnetMaskStr Subnet mask + * @param outBcastStr Stores the broadcast address + * @return RETURN_OK upon success else returned error code. + ****************************************************************************/ +int WanManager_GetBCastFromIpSubnetMask(const char *inIpStr, const char *inSubnetMaskStr, char *outBcastStr); + +/*************************************************************************** + * @brief API used to update ipv4 gateway + * @param ipv4Info pointer to dhcpv4_data_t holds the IPv4 configuration + * @return RETURN_OK upon success else returned error code. + ****************************************************************************/ +int WanManager_AddGatewayRoute(const WANMGR_IPV4_DATA* ipv4Info); + +/*************************************************************************** + * @brief API used to start PPP client application. + * @param pcInterfaceName Interface name on which the dhcpv6 needs to start + * @param isPPP indicates PPP enabled or nor + * @return ANSC_STATUS_SUCCESS upon success else returned error code. + ***************************************************************************/ +ANSC_STATUS WanManager_CreatePPPSession(DML_WAN_IFACE* pInterface); + +/*************************************************************************** + * @brief API used to start PPP client application. + * @param pcInterfaceName Interface name on which the dhcpv6 needs to start + * @param isPPP indicates PPP enabled or nor + * @return ANSC_STATUS_SUCCESS upon success else returned error code. + ***************************************************************************/ +ANSC_STATUS WanManager_DeletePPPSession(DML_WAN_IFACE* pInterface); + + +ANSC_STATUS WanManager_getGloballyUniqueIfAddr6(const char *ifname, char *ipAddr, uint32_t *prefixLen); + +#ifdef FEATURE_802_1P_COS_MARKING +ANSC_HANDLE WanManager_AddIfaceMarking(DML_WAN_IFACE* pWanDmlIface, ULONG* pInsNumber); +#endif /* * FEATURE_802_1P_COS_MARKING */ +ANSC_STATUS WanManager_CheckGivenTypeExists(INT IfIndex, UINT uiTotalIfaces, DML_WAN_IFACE_TYPE priorityType, INT priority, BOOL *Status); +ANSC_STATUS WanManager_CheckGivenPriorityExists(INT IfIndex, UINT uiTotalIfaces, INT priority, DML_WAN_IFACE_TYPE priorityType, BOOL *Status); +#endif // _WANMGR_NET_UTILS_H_ diff --git a/source/WanManager/wanmgr_platform_events.c b/source/WanManager/wanmgr_platform_events.c new file mode 100644 index 00000000..f95f9441 --- /dev/null +++ b/source/WanManager/wanmgr_platform_events.c @@ -0,0 +1,81 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2015 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +#include "wanmgr_platform_events.h" +#include "wanmgr_sysevents.h" +#include "platform_hal.h" + + +ANSC_STATUS WanMgr_UpdatePlatformStatus(eWanMgrPlatformStatus platform_status) +{ + ANSC_STATUS retStatus = ANSC_STATUS_SUCCESS; + +#ifdef _HUB4_PRODUCT_REQ_ + + char region[BUFLEN_16] = {0}; + + switch(platform_status) + { + case WANMGR_DISCONNECTED: + wanmgr_sysevents_setWanLedState(LED_OFF_STR); + break; + case WANMGR_LINK_UP: + wanmgr_sysevents_setWanLedState(LED_FLASHING_AMBER_STR); + break; + case WANMGR_LINK_V6UP_V4DOWN: + if(platform_hal_GetRouterRegion(region) == RETURN_OK) + { + if(strncmp(region, "IT", sizeof(region)) == 0) + { + wanmgr_sysevents_setWanLedState(LED_FLASHING_GREEN_STR); + } + else + { + wanmgr_sysevents_setWanLedState(LED_SOLID_AMBER_STR); + } + } + break; + case WANMGR_LINK_V4UP_V6DOWN: + if(platform_hal_GetRouterRegion(region) == RETURN_OK) + { + if(strncmp(region, "IT", sizeof(region)) == 0) + { + wanmgr_sysevents_setWanLedState(LED_SOLID_AMBER_STR); + } + else + { + wanmgr_sysevents_setWanLedState(LED_SOLID_GREEN_STR); + } + } + break; + case WANMGR_CONNECTING: + wanmgr_sysevents_setWanLedState(LED_SOLID_AMBER_STR); + break; + case WANMGR_CONNECTED: + wanmgr_sysevents_setWanLedState(LED_SOLID_GREEN_STR); + break; + default: + retStatus = ANSC_STATUS_FAILURE; + break; + + } +#endif //_HUB4_PRODUCT_REQ_ + + return retStatus; +} diff --git a/source/WanManager/wanmgr_platform_events.h b/source/WanManager/wanmgr_platform_events.h new file mode 100644 index 00000000..2f023580 --- /dev/null +++ b/source/WanManager/wanmgr_platform_events.h @@ -0,0 +1,71 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2015 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + + +#ifndef _WANMGR_PLATFORM_EVENTS_H_ +#define _WANMGR_PLATFORM_EVENTS_H_ +/* ---- Global Types -------------------------- */ +#include +#include +#include +#include +#include +#include +#include "wanmgr_rdkbus_common.h" + +#ifdef _HUB4_PRODUCT_REQ_ + +#define CONSOLE_LOG_FILE "/rdklogs/logs/Consolelog.txt.0" +#define LOG_CONSOLE(fmt ...) {\ + FILE *fp = NULL;\ + fp = fopen ( CONSOLE_LOG_FILE, "a+");\ + if (fp)\ + {\ + fprintf(fp,fmt);\ + fclose(fp);\ + }\ + }\ + + +#else + +#define LOG_CONSOLE() + +#endif //_HUB4_PRODUCT_REQ_ + + +typedef enum +{ + WANMGR_DISCONNECTED = 1, + WANMGR_LINK_UP, + WANMGR_LINK_V6UP_V4DOWN, + WANMGR_LINK_V4UP_V6DOWN, + WANMGR_CONNECTING, + WANMGR_CONNECTED +} eWanMgrPlatformStatus; + + +/*************************************************************************** + * @brief Function used to inform the platform the status of WAN Manager + * @param platform_status Current WAN Manager status + * @return ANSC_STATUS_SUCCESS upon success else returned error code. + ***************************************************************************/ +ANSC_STATUS WanMgr_UpdatePlatformStatus(eWanMgrPlatformStatus platform_status); + +#endif /*_WANMGR_PLATFORM_EVENTS_H_*/ diff --git a/source/WanManager/wanmgr_policy_fm_impl.c b/source/WanManager/wanmgr_policy_fm_impl.c new file mode 100644 index 00000000..bf2634f2 --- /dev/null +++ b/source/WanManager/wanmgr_policy_fm_impl.c @@ -0,0 +1,381 @@ +/* + If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2019 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +/* ---- Include Files ---------------------------------------- */ +#include +#include +#include +#include +#include "wanmgr_controller.h" +#include "wanmgr_data.h" +#include "wanmgr_rdkbus_utils.h" +#include "wanmgr_interface_sm.h" +#include "wanmgr_platform_events.h" + +/* ---- Global Constants -------------------------- */ +#define LOOP_TIMEOUT 500000 // timeout in milliseconds. This is the state machine loop interval + +/* Fixed mode policy */ +typedef enum { + STATE_FIXING_WAN_INTERFACE = 0, + STATE_FIXED_WAN_INTERFACE_DOWN, + STATE_FIXED_WAN_INTERFACE_UP +} WcFmPolicyState_t; + + +/* STATES */ +static WcFmPolicyState_t State_FixingWanInterface(WanMgr_Policy_Controller_t* pWanController); +static WcFmPolicyState_t State_FixedWanInterfaceDown(WanMgr_Policy_Controller_t* pWanController); +static WcFmPolicyState_t State_FixedWanInterfaceUp(WanMgr_Policy_Controller_t* pWanController); + +/* TRANSITIONS */ +static WcFmPolicyState_t Transition_Start(WanMgr_Policy_Controller_t* pWanController); +static WcFmPolicyState_t Transition_WanInterfaceFixed(WanMgr_Policy_Controller_t* pWanController); +static WcFmPolicyState_t Transition_FixedInterfaceDown(WanMgr_Policy_Controller_t* pWanController); +static WcFmPolicyState_t Transition_FixedInterfaceUp(WanMgr_Policy_Controller_t* pWanController); +static WcFmPolicyState_t Transition_FixedInterfaceChanged(WanMgr_Policy_Controller_t* pWanController); + + +/*********************************************************************************/ +/**************************** ACTIONS ********************************************/ +/*********************************************************************************/ +static INT WanMgr_Policy_FM_SelectWANActive(void) +{ + UINT uiLoopCount; + INT iActiveWanIdx = -1; + UINT uiTotalIfaces = -1; + INT iActivePriority = DML_WAN_IFACE_PRIORITY_MAX; + + //Get uiTotalIfaces + WanMgr_IfaceCtrl_Data_t* pWanIfaceCtrl = WanMgr_GetIfaceCtrl_locked(); + if(pWanIfaceCtrl != NULL) + { + uiTotalIfaces = pWanIfaceCtrl->ulTotalNumbWanInterfaces; + + WanMgrDml_GetIfaceCtrl_release(pWanIfaceCtrl); + } + + if(uiTotalIfaces > 0) + { + // Check the policy to determine if any primary interface should be used for WAN + for( uiLoopCount = 0; uiLoopCount < uiTotalIfaces; uiLoopCount++ ) + { + + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(uiLoopCount); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanIfaceData = &(pWanDmlIfaceData->data); + if ((pWanIfaceData->Wan.Enable == TRUE) && (pWanIfaceData->Wan.Type == WAN_IFACE_TYPE_PRIMARY)) + { + if(pWanIfaceData->Wan.Priority < iActivePriority) + { + if(pWanIfaceData->Wan.Priority >= 0) + { + iActiveWanIdx = uiLoopCount; + iActivePriority = pWanIfaceData->Wan.Priority; + } + } + } + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + } + + return iActiveWanIdx; +} + +/*********************************************************************************/ +/************************** TRANSITIONS ******************************************/ +/*********************************************************************************/ +static WcFmPolicyState_t Transition_Start(WanMgr_Policy_Controller_t* pWanController) +{ + WanMgr_UpdatePlatformStatus(WANMGR_DISCONNECTED); + return STATE_FIXING_WAN_INTERFACE; +} + +static WcFmPolicyState_t Transition_WanInterfaceFixed(WanMgr_Policy_Controller_t* pWanController) +{ + DML_WAN_IFACE* pFixedInterface = NULL; + + if((pWanController != NULL) && (pWanController->pWanActiveIfaceData != NULL)) + { + pFixedInterface = &(pWanController->pWanActiveIfaceData->data); + } + + if(pFixedInterface == NULL) + { + return STATE_FIXING_WAN_INTERFACE; + } + + //ActiveLink + pFixedInterface->Wan.ActiveLink = TRUE; + + WanMgr_UpdatePlatformStatus(WANMGR_LINK_UP); + + return STATE_FIXED_WAN_INTERFACE_DOWN; +} + + +static WcFmPolicyState_t Transition_FixedInterfaceDown(WanMgr_Policy_Controller_t* pWanController) +{ + WanMgr_UpdatePlatformStatus(WANMGR_DISCONNECTED); + return STATE_FIXED_WAN_INTERFACE_DOWN; +} + + +static WcFmPolicyState_t Transition_FixedInterfaceUp(WanMgr_Policy_Controller_t* pWanController) +{ + DML_WAN_IFACE* pFixedInterface = NULL; + WanMgr_IfaceSM_Controller_t wanIfCtrl; + + if((pWanController != NULL) && (pWanController->pWanActiveIfaceData != NULL)) + { + pFixedInterface = &(pWanController->pWanActiveIfaceData->data); + } + + if(pFixedInterface == NULL) + { + return STATE_FIXING_WAN_INTERFACE; + } + + WanMgr_UpdatePlatformStatus(WANMGR_CONNECTING); + + /* Starts an instance of the WAN Interface State Machine on + the interface to begin configuring the WAN link */ + WanMgr_IfaceSM_Init(&wanIfCtrl, pFixedInterface->uiIfaceIdx); + WanMgr_StartInterfaceStateMachine(&wanIfCtrl); + + return STATE_FIXED_WAN_INTERFACE_UP; +} + +static WcFmPolicyState_t Transition_FixedInterfaceChanged(WanMgr_Policy_Controller_t* pWanController) +{ + DML_WAN_IFACE* pFixedInterface = NULL; + + if((pWanController != NULL) && (pWanController->pWanActiveIfaceData != NULL)) + { + pFixedInterface = &(pWanController->pWanActiveIfaceData->data); + } + + if(pFixedInterface == NULL) + { + return STATE_FIXING_WAN_INTERFACE; + } + + /* Sets Wan.Status to DISABLED for the current active interface */ + pFixedInterface->Wan.Status = WAN_IFACE_STATUS_DISABLED; + + //ActiveLink + pFixedInterface->Wan.ActiveLink = TRUE; + + return STATE_FIXING_WAN_INTERFACE; +} + + +/*********************************************************************************/ +/**************************** STATES *********************************************/ +/*********************************************************************************/ +static WcFmPolicyState_t State_FixingWanInterface(WanMgr_Policy_Controller_t* pWanController) +{ + if(pWanController == NULL) + { + return ANSC_STATUS_FAILURE; + } + + pWanController->activeInterfaceIdx = WanMgr_Policy_FM_SelectWANActive(); + + + if(pWanController->activeInterfaceIdx != -1) + { + return Transition_WanInterfaceFixed(pWanController); + } + + return STATE_FIXING_WAN_INTERFACE; +} + +static WcFmPolicyState_t State_FixedWanInterfaceDown(WanMgr_Policy_Controller_t* pWanController) +{ + int iLoopCount; + INT iSelectWanIdx = -1; + DML_WAN_IFACE* pFixedInterface = NULL; + + if((pWanController != NULL) && (pWanController->pWanActiveIfaceData != NULL)) + { + pFixedInterface = &(pWanController->pWanActiveIfaceData->data); + } + + if(pFixedInterface == NULL) + { + return STATE_FIXING_WAN_INTERFACE; + } + + + if((pFixedInterface->Phy.Status == WAN_IFACE_PHY_STATUS_UP || + pFixedInterface->Phy.Status == WAN_IFACE_PHY_STATUS_INITIALIZING) && + pWanController->WanEnable && + pFixedInterface->Wan.Status == WAN_IFACE_STATUS_DISABLED && + pFixedInterface->Wan.LinkStatus == WAN_IFACE_LINKSTATUS_DOWN) + { + return Transition_FixedInterfaceUp(pWanController); + } + + if( pFixedInterface->Wan.Enable != TRUE || + pFixedInterface->Wan.Type != WAN_IFACE_TYPE_PRIMARY) + { + return Transition_FixedInterfaceChanged(pWanController); + } + + /* Wan.Priority of the Fixed Interface is no longer the highest of all Primary interfaces */ + iSelectWanIdx = WanMgr_Policy_FM_SelectWANActive(); + + if(iSelectWanIdx != pWanController->activeInterfaceIdx) + { + return Transition_FixedInterfaceChanged(pWanController); + } + + return STATE_FIXED_WAN_INTERFACE_DOWN; +} + +static WcFmPolicyState_t State_FixedWanInterfaceUp(WanMgr_Policy_Controller_t* pWanController) +{ + INT iSelectWanIdx = -1; + DML_WAN_IFACE* pFixedInterface = NULL; + + if((pWanController != NULL) && (pWanController->pWanActiveIfaceData != NULL)) + { + pFixedInterface = &(pWanController->pWanActiveIfaceData->data); + } + + if(pFixedInterface == NULL) + { + return STATE_FIXED_WAN_INTERFACE_DOWN; + } + + if( pFixedInterface->Phy.Status == WAN_IFACE_PHY_STATUS_DOWN || pWanController->WanEnable == FALSE) + { + return Transition_FixedInterfaceDown(pWanController); + } + + if( pFixedInterface->Wan.Enable == FALSE || pFixedInterface->Wan.Type != WAN_IFACE_TYPE_PRIMARY) + { + return Transition_FixedInterfaceChanged(pWanController); + } + + /* Wan.Priority of the Fixed Interface is no longer the highest of all Primary interfaces */ + iSelectWanIdx = WanMgr_Policy_FM_SelectWANActive(); + + if(iSelectWanIdx != pWanController->activeInterfaceIdx) + { + return Transition_FixedInterfaceChanged(pWanController); + } + + return STATE_FIXED_WAN_INTERFACE_UP; +} + + +/*********************************************************************************/ +/*********************************************************************************/ +/*********************************************************************************/ +/* WanMgr_Policy_FixedModePolicy */ +ANSC_STATUS WanMgr_Policy_FixedModePolicy(void) +{ + CcspTraceInfo(("%s %d \n", __FUNCTION__, __LINE__)); + + //detach thread from caller stack + pthread_detach(pthread_self()); + + //policy variables + ANSC_STATUS retStatus = ANSC_STATUS_SUCCESS; + WanMgr_Policy_Controller_t WanPolicyCtrl; + WcFmPolicyState_t fm_sm_state; + bool bRunning = true; + + // event handler + int n = 0; + struct timeval tv; + + + if(WanMgr_Controller_PolicyCtrlInit(&WanPolicyCtrl) != ANSC_STATUS_SUCCESS) + { + CcspTraceError(("%s %d Policy Controller Error \n", __FUNCTION__, __LINE__)); + return ANSC_STATUS_FAILURE; + } + + CcspTraceInfo(("%s %d Fixed Mode Policy Thread Starting \n", __FUNCTION__, __LINE__)); + + // initialise state machine + fm_sm_state = Transition_Start(&WanPolicyCtrl); // do this first before anything else to init variables + + while (bRunning) + { + /* Wait up to 500 milliseconds */ + tv.tv_sec = 0; + tv.tv_usec = LOOP_TIMEOUT; + + n = select(0, NULL, NULL, NULL, &tv); + if (n < 0) + { + /* interrupted by signal or something, continue */ + continue; + } + + //Update Wan config + WanMgr_Config_Data_t* pWanConfigData = WanMgr_GetConfigData_locked(); + if(pWanConfigData != NULL) + { + WanPolicyCtrl.WanEnable = pWanConfigData->data.Enable; + + WanMgrDml_GetConfigData_release(pWanConfigData); + } + + //Lock Iface Data + WanPolicyCtrl.pWanActiveIfaceData = WanMgr_GetIfaceData_locked(WanPolicyCtrl.activeInterfaceIdx); + + // process state + switch (fm_sm_state) + { + case STATE_FIXING_WAN_INTERFACE: + fm_sm_state = State_FixingWanInterface(&WanPolicyCtrl); + break; + case STATE_FIXED_WAN_INTERFACE_UP: + fm_sm_state = State_FixedWanInterfaceUp(&WanPolicyCtrl); + break; + case STATE_FIXED_WAN_INTERFACE_DOWN: + fm_sm_state = State_FixedWanInterfaceDown(&WanPolicyCtrl); + break; + default: + CcspTraceInfo(("%s %d - Case: default \n", __FUNCTION__, __LINE__)); + bRunning = false; + retStatus = ANSC_STATUS_FAILURE; + break; + } + + //Release Lock Iface Data + if(WanPolicyCtrl.pWanActiveIfaceData != NULL) + { + WanMgrDml_GetIfaceData_release(WanPolicyCtrl.pWanActiveIfaceData); + } + } + + + CcspTraceInfo(("%s %d - Exit from state machine\n", __FUNCTION__, __LINE__)); + + return retStatus; +} diff --git a/source/WanManager/wanmgr_policy_fmob_impl.c b/source/WanManager/wanmgr_policy_fmob_impl.c new file mode 100644 index 00000000..c10e865b --- /dev/null +++ b/source/WanManager/wanmgr_policy_fmob_impl.c @@ -0,0 +1,323 @@ +/* + If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2019 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +/* ---- Include Files ---------------------------------------- */ +#include +#include +#include +#include +#include "wanmgr_controller.h" +#include "wanmgr_data.h" +#include "wanmgr_rdkbus_utils.h" +#include "wanmgr_interface_sm.h" +#include "wanmgr_platform_events.h" + +/* ---- Global Constants -------------------------- */ +#define LOOP_TIMEOUT 500000 // timeout in milliseconds. This is the state machine loop interval + + +/* fixed mode policy states */ +typedef enum { + STATE_FIXING_WAN_INTERFACE = 0, + STATE_FIXED_WAN_INTERFACE_DOWN, + STATE_FIXED_WAN_INTERFACE_UP +} WcFmobPolicyState_t; + + +/* STATES */ +static WcFmobPolicyState_t State_FixingWanInterface(WanMgr_Policy_Controller_t* pWanController); +static WcFmobPolicyState_t State_FixedWanInterfaceDown(WanMgr_Policy_Controller_t* pWanController); +static WcFmobPolicyState_t State_FixedWanInterfaceUp(WanMgr_Policy_Controller_t* pWanController); + +/* TRANSITIONS */ +static WcFmobPolicyState_t Transition_Start(WanMgr_Policy_Controller_t* pWanController); +static WcFmobPolicyState_t Transition_WanInterfaceFixed(WanMgr_Policy_Controller_t* pWanController); +static WcFmobPolicyState_t Transition_FixedInterfaceUp(WanMgr_Policy_Controller_t* pWanController); +static WcFmobPolicyState_t Transition_FixedInterfaceDown(WanMgr_Policy_Controller_t* pWanController); + +/*********************************************************************************/ +/**************************** ACTIONS ********************************************/ +/*********************************************************************************/ +static INT WanMgr_Policy_FM_SelectWANActive(void) +{ + UINT uiLoopCount; + INT iActiveWanIdx = -1; + UINT uiTotalIfaces = -1; + INT iActivePriority = DML_WAN_IFACE_PRIORITY_MAX; + + //Get uiTotalIfaces + WanMgr_IfaceCtrl_Data_t* pWanIfaceCtrl = WanMgr_GetIfaceCtrl_locked(); + if(pWanIfaceCtrl != NULL) + { + uiTotalIfaces = pWanIfaceCtrl->ulTotalNumbWanInterfaces; + WanMgrDml_GetIfaceCtrl_release(pWanIfaceCtrl); + } + + if(uiTotalIfaces > 0) + { + // Check the policy to determine if any primary interface should be used for WAN + for( uiLoopCount = 0; uiLoopCount < uiTotalIfaces; uiLoopCount++ ) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(uiLoopCount); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanIfaceData = &(pWanDmlIfaceData->data); + if ((pWanIfaceData->Wan.Enable == TRUE) && (pWanIfaceData->Wan.Type == WAN_IFACE_TYPE_PRIMARY)) + { + if(pWanIfaceData->Wan.Priority < iActivePriority) + { + if(pWanIfaceData->Wan.Priority >= 0) + { + iActiveWanIdx = uiLoopCount; + iActivePriority = pWanIfaceData->Wan.Priority; + } + } + } + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + } + + return iActiveWanIdx; +} + + +/*********************************************************************************/ +/************************** TRANSITIONS ******************************************/ +/*********************************************************************************/ +static WcFmobPolicyState_t Transition_Start(WanMgr_Policy_Controller_t* pWanController) +{ + WanMgr_UpdatePlatformStatus(WANMGR_DISCONNECTED); + CcspTraceInfo(("%s %d - State changed to STATE_FIXING_WAN_INTERFACE \n", __FUNCTION__, __LINE__)); + return STATE_FIXING_WAN_INTERFACE; +} + +static WcFmobPolicyState_t Transition_WanInterfaceFixed(WanMgr_Policy_Controller_t* pWanController) +{ + DML_WAN_IFACE* pFixedInterface = NULL; + + if((pWanController != NULL) && (pWanController->pWanActiveIfaceData != NULL)) + { + pFixedInterface = &(pWanController->pWanActiveIfaceData->data); + } + + if(pFixedInterface == NULL) + { + return STATE_FIXING_WAN_INTERFACE; + } + + //ActiveLink + pFixedInterface->Wan.ActiveLink = TRUE; + + WanMgr_UpdatePlatformStatus(WANMGR_LINK_UP); + + CcspTraceInfo(("%s %d - State changed to STATE_FIXED_WAN_INTERFACE_DOWN \n", __FUNCTION__, __LINE__)); + return STATE_FIXED_WAN_INTERFACE_DOWN; +} + +static WcFmobPolicyState_t Transition_FixedInterfaceDown(WanMgr_Policy_Controller_t* pWanController) +{ + CcspTraceInfo(("%s %d - State changed to STATE_FIXED_WAN_INTERFACE_DOWN \n", __FUNCTION__, __LINE__)); + WanMgr_UpdatePlatformStatus(WANMGR_DISCONNECTED); + return STATE_FIXED_WAN_INTERFACE_DOWN; +} + +static WcFmobPolicyState_t Transition_FixedInterfaceUp(WanMgr_Policy_Controller_t* pWanController) +{ + DML_WAN_IFACE* pFixedInterface = NULL; + WanMgr_IfaceSM_Controller_t wanIfCtrl; + + if((pWanController != NULL) && (pWanController->pWanActiveIfaceData != NULL)) + { + pFixedInterface = &(pWanController->pWanActiveIfaceData->data); + } + + if(pFixedInterface == NULL) + { + return STATE_FIXING_WAN_INTERFACE; + } + + WanMgr_UpdatePlatformStatus(WANMGR_CONNECTING); + + /* Starts an instance of the WAN Interface State Machine on the interface to begin configuring the WAN link */ + WanMgr_IfaceSM_Init(&wanIfCtrl, pFixedInterface->uiIfaceIdx); + WanMgr_StartInterfaceStateMachine(&wanIfCtrl); + + CcspTraceInfo(("%s %d - State changed to STATE_FIXED_WAN_INTERFACE_UP \n", __FUNCTION__, __LINE__)); + return STATE_FIXED_WAN_INTERFACE_UP; +} + +/*********************************************************************************/ +/**************************** STATES *********************************************/ +/*********************************************************************************/ +static WcFmobPolicyState_t State_FixingWanInterface(WanMgr_Policy_Controller_t* pWanController) +{ + if(pWanController == NULL) + { + return ANSC_STATUS_FAILURE; + } + + pWanController->activeInterfaceIdx = WanMgr_Policy_FM_SelectWANActive(); + if(pWanController->activeInterfaceIdx != -1) + { + return Transition_WanInterfaceFixed(pWanController); + } + + return STATE_FIXING_WAN_INTERFACE; +} + +static WcFmobPolicyState_t State_FixedWanInterfaceDown(WanMgr_Policy_Controller_t* pWanController) +{ + int iLoopCount; + INT iSelectWanIdx = -1; + DML_WAN_IFACE* pFixedInterface = NULL; + + if((pWanController != NULL) && (pWanController->pWanActiveIfaceData != NULL)) + { + pFixedInterface = &(pWanController->pWanActiveIfaceData->data); + } + + if(pFixedInterface == NULL) + { + return STATE_FIXING_WAN_INTERFACE; + } + + if( pWanController->WanEnable == TRUE && + (pFixedInterface->Phy.Status == WAN_IFACE_PHY_STATUS_UP || + pFixedInterface->Phy.Status == WAN_IFACE_PHY_STATUS_INITIALIZING) && + pFixedInterface->Wan.Status == WAN_IFACE_STATUS_DISABLED && + pFixedInterface->Wan.LinkStatus == WAN_IFACE_LINKSTATUS_DOWN ) + { + return Transition_FixedInterfaceUp(pWanController); + } + + return STATE_FIXED_WAN_INTERFACE_DOWN; +} + +static WcFmobPolicyState_t State_FixedWanInterfaceUp(WanMgr_Policy_Controller_t* pWanController) +{ + DML_WAN_IFACE* pFixedInterface = NULL; + + if((pWanController != NULL) && (pWanController->pWanActiveIfaceData != NULL)) + { + pFixedInterface = &(pWanController->pWanActiveIfaceData->data); + } + + if(pFixedInterface == NULL) + { + return STATE_FIXED_WAN_INTERFACE_DOWN; + } + + if( pWanController->WanEnable == FALSE || + pFixedInterface->Phy.Status == WAN_IFACE_PHY_STATUS_DOWN) + { + return Transition_FixedInterfaceDown(pWanController); + } + + return STATE_FIXED_WAN_INTERFACE_UP; +} + +/*********************************************************************************/ +/*********************************************************************************/ +/*********************************************************************************/ +/* WanMgr_Policy_FixedModeOnBootupPolicy */ +ANSC_STATUS WanMgr_Policy_FixedModeOnBootupPolicy(void) +{ + CcspTraceInfo(("%s %d \n", __FUNCTION__, __LINE__)); + + //detach thread from caller stack + pthread_detach(pthread_self()); + + //policy variables + ANSC_STATUS retStatus = ANSC_STATUS_SUCCESS; + WanMgr_Policy_Controller_t WanPolicyCtrl; + WcFmobPolicyState_t fmob_sm_state; + bool bRunning = true; + + // event handler + int n = 0; + struct timeval tv; + + if(WanMgr_Controller_PolicyCtrlInit(&WanPolicyCtrl) != ANSC_STATUS_SUCCESS) + { + CcspTraceError(("%s %d Policy Controller Error \n", __FUNCTION__, __LINE__)); + return ANSC_STATUS_FAILURE; + } + + CcspTraceInfo(("%s %d Fixed Mode On Bootup Policy Thread Starting \n", __FUNCTION__, __LINE__)); + + // initialise state machine + fmob_sm_state = Transition_Start(&WanPolicyCtrl); // do this first before anything else to init variables + + while (bRunning) + { + /* Wait up to 500 milliseconds */ + tv.tv_sec = 0; + tv.tv_usec = LOOP_TIMEOUT; + + n = select(0, NULL, NULL, NULL, &tv); + if (n < 0) + { + /* interrupted by signal or something, continue */ + continue; + } + + //Update Wan config + WanMgr_Config_Data_t* pWanConfigData = WanMgr_GetConfigData_locked(); + if(pWanConfigData != NULL) + { + WanPolicyCtrl.WanEnable = pWanConfigData->data.Enable; + WanMgrDml_GetConfigData_release(pWanConfigData); + } + + //Lock Iface Data + WanPolicyCtrl.pWanActiveIfaceData = WanMgr_GetIfaceData_locked(WanPolicyCtrl.activeInterfaceIdx); + + // process state + switch (fmob_sm_state) + { + case STATE_FIXING_WAN_INTERFACE: + fmob_sm_state = State_FixingWanInterface(&WanPolicyCtrl); + break; + case STATE_FIXED_WAN_INTERFACE_DOWN: + fmob_sm_state = State_FixedWanInterfaceDown(&WanPolicyCtrl); + break; + case STATE_FIXED_WAN_INTERFACE_UP: + fmob_sm_state = State_FixedWanInterfaceUp(&WanPolicyCtrl); + break; + default: + CcspTraceInfo(("%s %d - Case: default \n", __FUNCTION__, __LINE__)); + bRunning = false; + retStatus = ANSC_STATUS_FAILURE; + break; + } + + //Release Lock Iface Data + if(WanPolicyCtrl.pWanActiveIfaceData != NULL) + { + WanMgrDml_GetIfaceData_release(WanPolicyCtrl.pWanActiveIfaceData); + } + } + + CcspTraceInfo(("%s %d - Exit from state machine\n", __FUNCTION__, __LINE__)); + + return retStatus; +} + diff --git a/source/WanManager/wanmgr_policy_pp_impl.c b/source/WanManager/wanmgr_policy_pp_impl.c new file mode 100644 index 00000000..ecbc5dd5 --- /dev/null +++ b/source/WanManager/wanmgr_policy_pp_impl.c @@ -0,0 +1,758 @@ +/* + If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2019 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +/* ---- Include Files ---------------------------------------- */ +#include +#include +#include +#include +#include "wanmgr_controller.h" +#include "wanmgr_data.h" +#include "wanmgr_rdkbus_utils.h" +#include "wanmgr_interface_sm.h" +#include "wanmgr_platform_events.h" + +/* ---- Global Constants -------------------------- */ +#define LOOP_TIMEOUT 500000 // timeout in milliseconds. This is the state machine loop interval + + +/* primary priority policy */ +typedef enum { + STATE_INTERFACE_DOWN = 0, + STATE_PRIMARY_WAN_ACTIVE, + STATE_SECONDARY_WAN_ACTIVE, + STATE_PRIMARY_WAN_ACTIVE_SECONDARY_WAN_UP +} WcPpPolicyState_t; + + +/* STATES */ +static WcPpPolicyState_t State_WanDown(WanMgr_Policy_Controller_t* pWanController); +static WcPpPolicyState_t State_PrimaryWanActive(WanMgr_Policy_Controller_t* pWanController); +static WcPpPolicyState_t State_SecondaryWanActive(WanMgr_Policy_Controller_t* pWanController); +static WcPpPolicyState_t State_PrimaryWanActiveSecondaryWanUp(WanMgr_Policy_Controller_t* pWanController); + +/* TRANSITIONS */ +static WcPpPolicyState_t Transition_Start(WanMgr_Policy_Controller_t* pWanController); +static WcPpPolicyState_t Transition_PrimaryInterfaceSelected(WanMgr_Policy_Controller_t* pWanController); +static WcPpPolicyState_t Transition_PrimaryInterfaceDeSelected(WanMgr_Policy_Controller_t* pWanController); +static WcPpPolicyState_t Transition_PrimaryInterfaceChanged(WanMgr_Policy_Controller_t* pWanController); +static WcPpPolicyState_t Transition_SecondaryInterfaceSelected(WanMgr_Policy_Controller_t* pWanController); +static WcPpPolicyState_t Transition_SecondaryInterfaceDeSelected(WanMgr_Policy_Controller_t* pWanController); +static WcPpPolicyState_t Transition_SecondaryInterfaceUp(WanMgr_Policy_Controller_t* pWanController); +static WcPpPolicyState_t Transition_SecondaryInterfaceDown(WanMgr_Policy_Controller_t* pWanController); + + +/*********************************************************************************/ +/**************************** ACTIONS ********************************************/ +/*********************************************************************************/ +static void WanMgr_Policy_FM_SelectWANActive(WanMgr_Policy_Controller_t* pWanController, INT* pPrimaryInterface, INT* pSecondaryInterface) +{ + UINT uiLoopCount; + UINT uiTotalIfaces = -1; + INT iSelPrimaryInterface = -1; + INT iSelSecondaryInterface = -1; + INT iSelPrimaryPriority = DML_WAN_IFACE_PRIORITY_MAX; + INT iSelSecondaryPriority = DML_WAN_IFACE_PRIORITY_MAX; + + //Get uiTotalIfaces + WanMgr_IfaceCtrl_Data_t* pWanIfaceCtrl = WanMgr_GetIfaceCtrl_locked(); + if(pWanIfaceCtrl != NULL) + { + uiTotalIfaces = pWanIfaceCtrl->ulTotalNumbWanInterfaces; + + WanMgrDml_GetIfaceCtrl_release(pWanIfaceCtrl); + } + + if(uiTotalIfaces > 0) + { + // Check the policy to determine if any primary interface should be used for WAN + if(pWanController->WanEnable == TRUE) + { + for( uiLoopCount = 0; uiLoopCount < uiTotalIfaces; uiLoopCount++ ) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(uiLoopCount); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanIfaceData = &(pWanDmlIfaceData->data); + + if (pWanIfaceData->Wan.Enable == TRUE && + (pWanIfaceData->Phy.Status == WAN_IFACE_PHY_STATUS_UP || + pWanIfaceData->Phy.Status == WAN_IFACE_PHY_STATUS_INITIALIZING)) + { + if(pWanIfaceData->Wan.Type == WAN_IFACE_TYPE_PRIMARY) + { + if(pWanIfaceData->Wan.Priority < iSelPrimaryPriority) + { + if(pWanIfaceData->Wan.Priority >= 0) + { + iSelPrimaryInterface = uiLoopCount; + iSelPrimaryPriority = pWanIfaceData->Wan.Priority; + } + } + } + else + { + if(pWanIfaceData->Wan.Priority < iSelSecondaryPriority) + { + if(pWanIfaceData->Wan.Priority >= 0) + { + iSelSecondaryInterface = uiLoopCount; + iSelSecondaryPriority = pWanIfaceData->Wan.Priority; + } + } + } + } + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + } + } + + *pPrimaryInterface = iSelPrimaryInterface; + *pSecondaryInterface = iSelSecondaryInterface; + + return ; +} + +static bool WanMgr_CheckAllIfacesDown(void) +{ + bool bAllDown = TRUE; + UINT uiLoopCount; + UINT uiTotalIfaces = 0; + + //Get uiTotalIfaces + WanMgr_IfaceCtrl_Data_t* pWanIfaceCtrl = WanMgr_GetIfaceCtrl_locked(); + if(pWanIfaceCtrl != NULL) + { + uiTotalIfaces = pWanIfaceCtrl->ulTotalNumbWanInterfaces; + + WanMgrDml_GetIfaceCtrl_release(pWanIfaceCtrl); + } + else + { + bAllDown = FALSE; + } + + if(uiTotalIfaces > 0) + { + for( uiLoopCount = 0; uiLoopCount < uiTotalIfaces; uiLoopCount++ ) + { + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(uiLoopCount); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanIfaceData = &(pWanDmlIfaceData->data); + + if (pWanIfaceData->Wan.Status != WAN_IFACE_STATUS_DISABLED) + { + bAllDown = FALSE; + } + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + } + + return bAllDown; +} + +/*********************************************************************************/ +/************************** TRANSITIONS ******************************************/ +/*********************************************************************************/ +static WcPpPolicyState_t Transition_Start(WanMgr_Policy_Controller_t* pWanController) +{ + if(pWanController == NULL) + { + CcspTraceError(("%s %d pWanController object is NULL \n", __FUNCTION__, __LINE__)); + return ANSC_STATUS_FAILURE; + } + + WanMgr_UpdatePlatformStatus(WANMGR_DISCONNECTED); + + CcspTraceInfo(("%s %d - State changed to STATE_INTERFACE_DOWN \n", __FUNCTION__, __LINE__)); + return STATE_INTERFACE_DOWN; +} + +static WcPpPolicyState_t Transition_PrimaryInterfaceSelected(WanMgr_Policy_Controller_t* pWanController) +{ + DML_WAN_IFACE* pActiveInterface = NULL; + WanMgr_IfaceSM_Controller_t wanIfCtrl; + + if(pWanController == NULL) + { + CcspTraceError(("%s %d pWanController object is NULL \n", __FUNCTION__, __LINE__)); + return ANSC_STATUS_FAILURE; + } + + /* If Secondary WAN is Active */ + if(pWanController->pWanActiveIfaceData != NULL) + { + /* Secondary WAN is Active */ + pActiveInterface = &(pWanController->pWanActiveIfaceData->data); + + //Set ActiveLink to FALSE + pActiveInterface->Wan.ActiveLink = FALSE; + } + + + /* Select Primary WAN as Active */ + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pWanController->activeInterfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanIfaceData = &(pWanDmlIfaceData->data); + + //Set ActiveLink to TRUE + pWanIfaceData->Wan.ActiveLink = TRUE; + + WanMgr_IfaceSM_Init(&wanIfCtrl, pWanIfaceData->uiIfaceIdx); + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + + + WanMgr_UpdatePlatformStatus(WANMGR_CONNECTING); + + /* Starts an instance of the WAN Interface State Machine on + the interface to begin configuring the WAN link */ + WanMgr_StartInterfaceStateMachine(&wanIfCtrl); + +/* TODO: Disabling the below code to avoid conflict issues in interface state machines as we are using +erouter0 name for both primary and secondary connections. Once this issue is fixed the below code can +be enabled */ +#ifdef WAN_ENABLE_STANDBY + /* If Secondary WAN is DOWN : Change state to PrimaryWANActive */ + if(pWanController->selSecondaryInterfaceIdx < 0) + { + CcspTraceInfo(("%s %d - State changed to STATE_PRIMARY_WAN_ACTIVE \n", __FUNCTION__, __LINE__)); + return STATE_PRIMARY_WAN_ACTIVE; + } + + CcspTraceInfo(("%s %d - State changed to STATE_PRIMARY_WAN_ACTIVE_SECONDARY_WAN_UP \n", __FUNCTION__, __LINE__)); + return STATE_PRIMARY_WAN_ACTIVE_SECONDARY_WAN_UP; + +#else + CcspTraceInfo(("%s %d - State changed to STATE_PRIMARY_WAN_ACTIVE \n", __FUNCTION__, __LINE__)); + return STATE_PRIMARY_WAN_ACTIVE; +#endif //WAN_ENABLE_STANDBY +} + +static WcPpPolicyState_t Transition_PrimaryInterfaceDeSelected(WanMgr_Policy_Controller_t* pWanController) +{ + DML_WAN_IFACE* pActiveInterface = NULL; + + if(pWanController == NULL) + { + CcspTraceError(("%s %d pWanController object is NULL \n", __FUNCTION__, __LINE__)); + return ANSC_STATUS_FAILURE; + } + + if(pWanController->pWanActiveIfaceData == NULL) + { + return ANSC_STATUS_FAILURE; + } + + + pActiveInterface = &(pWanController->pWanActiveIfaceData->data); + + //Set ActiveLink to FALSE + pActiveInterface->Wan.ActiveLink = FALSE; + + + pWanController->activeInterfaceIdx = -1; + + WanMgr_UpdatePlatformStatus(WANMGR_DISCONNECTED); + + CcspTraceInfo(("%s %d - State changed to STATE_INTERFACE_DOWN \n", __FUNCTION__, __LINE__)); + return STATE_INTERFACE_DOWN; +} + +static WcPpPolicyState_t Transition_PrimaryInterfaceChanged(WanMgr_Policy_Controller_t* pWanController) +{ + DML_WAN_IFACE* pActiveInterface = NULL; + int selectedPrimaryInterface = -1; + int selectedSecondaryInterface = -1; + WanMgr_IfaceSM_Controller_t wanIfCtrl; + + if(pWanController == NULL) + { + CcspTraceError(("%s %d pWanController object is NULL \n", __FUNCTION__, __LINE__)); + return ANSC_STATUS_FAILURE; + } + + if(pWanController->pWanActiveIfaceData == NULL) + { + return ANSC_STATUS_FAILURE; + } + + pActiveInterface = &(pWanController->pWanActiveIfaceData->data); + + //Set ActiveLink to FALSE + pActiveInterface->Wan.ActiveLink = FALSE; + + pWanController->activeInterfaceIdx = -1; + + WanMgr_UpdatePlatformStatus(WANMGR_DISCONNECTED); + + WanMgr_Policy_FM_SelectWANActive(pWanController,&selectedPrimaryInterface, &selectedSecondaryInterface); + if (selectedPrimaryInterface != -1) + { + pWanController->activeInterfaceIdx = selectedPrimaryInterface; + + /* Select New Primary WAN as Active */ + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pWanController->activeInterfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanIfaceData = &(pWanDmlIfaceData->data); + + //Set ActiveLink to TRUE + pWanIfaceData->Wan.ActiveLink = TRUE; + WanMgr_IfaceSM_Init(&wanIfCtrl, pWanIfaceData->uiIfaceIdx); + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + + + WanMgr_UpdatePlatformStatus(WANMGR_CONNECTING); + + /* Starts an instance of the WAN Interface State Machine on + the interface to begin configuring the WAN link */ + WanMgr_StartInterfaceStateMachine(&wanIfCtrl); + } + + CcspTraceInfo(("%s %d - State changed to STATE_PRIMARY_WAN_ACTIVE_SECONDARY_WAN_UP \n", __FUNCTION__, __LINE__)); + return STATE_PRIMARY_WAN_ACTIVE_SECONDARY_WAN_UP; +} + +static WcPpPolicyState_t Transition_SecondaryInterfaceSelected(WanMgr_Policy_Controller_t* pWanController) +{ + DML_WAN_IFACE* pActiveInterface = NULL; + WanMgr_IfaceSM_Controller_t wanIfCtrl; + + if(pWanController == NULL) + { + CcspTraceError(("%s %d pWanController object is NULL \n", __FUNCTION__, __LINE__)); + return ANSC_STATUS_FAILURE; + } + + /* If Primary WAN is Active */ + if(pWanController->pWanActiveIfaceData != NULL) + { + pActiveInterface = &(pWanController->pWanActiveIfaceData->data); + + //Set ActiveLink to FALSE + pActiveInterface->Wan.ActiveLink = FALSE; + } + + + /* Select Secondary WAN as Active */ + pWanController->activeInterfaceIdx = pWanController->selSecondaryInterfaceIdx; + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pWanController->activeInterfaceIdx); + if(pWanDmlIfaceData == NULL) + { + CcspTraceInfo(("%s %d - (Error) State changed to STATE_INTERFACE_DOWN \n", __FUNCTION__, __LINE__)); + return STATE_INTERFACE_DOWN; + } + + DML_WAN_IFACE* pWanIfaceData = &(pWanDmlIfaceData->data); + + //Set ActiveLink to TRUE + pWanIfaceData->Wan.ActiveLink = TRUE; + WanMgr_IfaceSM_Init(&wanIfCtrl, pWanIfaceData->uiIfaceIdx); + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + + + WanMgr_UpdatePlatformStatus(WANMGR_CONNECTING); + + /* Starts an instance of the WAN Interface State Machine on + the interface to begin configuring the WAN link */ + WanMgr_StartInterfaceStateMachine(&wanIfCtrl); + + CcspTraceInfo(("%s %d - State changed to STATE_SECONDARY_WAN_ACTIVE \n", __FUNCTION__, __LINE__)); + return STATE_SECONDARY_WAN_ACTIVE; +} + +static WcPpPolicyState_t Transition_SecondaryInterfaceDeSelected(WanMgr_Policy_Controller_t* pWanController) +{ + DML_WAN_IFACE* pActiveInterface = NULL; + + if(pWanController == NULL) + { + CcspTraceError(("%s %d pWanController object is NULL \n", __FUNCTION__, __LINE__)); + return ANSC_STATUS_FAILURE; + } + + /* If Secondary WAN is Active */ + if(pWanController->pWanActiveIfaceData != NULL) + { + pActiveInterface = &(pWanController->pWanActiveIfaceData->data); + + //Set ActiveLink to FALSE + pActiveInterface->Wan.ActiveLink = FALSE; + } + + pWanController->activeInterfaceIdx = -1; + pWanController->selSecondaryInterfaceIdx = -1; + + + WanMgr_UpdatePlatformStatus(WANMGR_DISCONNECTED); + + CcspTraceInfo(("%s %d - State changed to STATE_INTERFACE_DOWN \n", __FUNCTION__, __LINE__)); + return STATE_INTERFACE_DOWN; +} + +static WcPpPolicyState_t Transition_SecondaryInterfaceUp(WanMgr_Policy_Controller_t* pWanController) +{ + DML_WAN_IFACE* pActiveInterface = NULL; + bool bSecondaryUp = false; + WanMgr_IfaceSM_Controller_t wanIfCtrl; + + if(pWanController == NULL) + { + CcspTraceError(("%s %d pWanController object is NULL \n", __FUNCTION__, __LINE__)); + return ANSC_STATUS_FAILURE; + } + + /* Get Secondary WAN info */ + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pWanController->selSecondaryInterfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanIfaceData = &(pWanDmlIfaceData->data); + + if (pWanIfaceData->Wan.Enable == TRUE && + pWanIfaceData->Wan.Status == WAN_IFACE_STATUS_DISABLED && + pWanIfaceData->Phy.Status == WAN_IFACE_PHY_STATUS_UP && + pWanIfaceData->Wan.LinkStatus == WAN_IFACE_LINKSTATUS_DOWN && + pWanIfaceData->Wan.Type == WAN_IFACE_TYPE_SECONDARY) + { + WanMgr_IfaceSM_Init(&wanIfCtrl, pWanIfaceData->uiIfaceIdx); + bSecondaryUp = true; + } + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + + if(bSecondaryUp == false) + { + pWanController->selSecondaryInterfaceIdx = -1; + CcspTraceInfo(("%s %d - State changed to STATE_PRIMARY_WAN_ACTIVE \n", __FUNCTION__, __LINE__)); + return STATE_PRIMARY_WAN_ACTIVE; + } + + + WanMgr_UpdatePlatformStatus(WANMGR_CONNECTING); + + /* Starts an instance of the WAN Interface State Machine on + the interface to begin configuring the WAN link */ + WanMgr_StartInterfaceStateMachine(&wanIfCtrl); + + + CcspTraceInfo(("%s %d - State changed to STATE_PRIMARY_WAN_ACTIVE_SECONDARY_WAN_UP \n", __FUNCTION__, __LINE__)); + return STATE_PRIMARY_WAN_ACTIVE_SECONDARY_WAN_UP; +} + +static WcPpPolicyState_t Transition_SecondaryInterfaceDown(WanMgr_Policy_Controller_t* pWanController) +{ + pWanController->selSecondaryInterfaceIdx = -1; + CcspTraceInfo(("%s %d - State changed to STATE_PRIMARY_WAN_ACTIVE \n", __FUNCTION__, __LINE__)); + return STATE_PRIMARY_WAN_ACTIVE; +} +/*********************************************************************************/ +/**************************** STATES *********************************************/ +/*********************************************************************************/ +static WcPpPolicyState_t State_WanDown(WanMgr_Policy_Controller_t* pWanController) +{ + int selectedPrimaryInterface = -1; + int selectedSecondaryInterface = -1; + + if(pWanController == NULL) + { + CcspTraceError(("%s %d pWanController object is NULL \n", __FUNCTION__, __LINE__)); + return ANSC_STATUS_FAILURE; + } + +#ifndef WAN_ENABLE_STANDBY + /* Waiting to tear down all in active wan connection */ + if(WanMgr_CheckAllIfacesDown() == FALSE) + { + return STATE_INTERFACE_DOWN; + } +#endif //WAN_ENABLE_STANDBY + + WanMgr_Policy_FM_SelectWANActive(pWanController, &selectedPrimaryInterface, &selectedSecondaryInterface); + + if(selectedPrimaryInterface != -1) + { + /* TODO: Implement selection timeout logic here */ + pWanController->activeInterfaceIdx = selectedPrimaryInterface; + return Transition_PrimaryInterfaceSelected(pWanController); + } + else if(selectedSecondaryInterface != -1) + { + /* TODO: Implement selection timeout logic here */ + pWanController->activeInterfaceIdx = selectedSecondaryInterface; + pWanController->selSecondaryInterfaceIdx = selectedSecondaryInterface; + return Transition_SecondaryInterfaceSelected(pWanController); + } + + return STATE_INTERFACE_DOWN; +} + +static WcPpPolicyState_t State_PrimaryWanActive(WanMgr_Policy_Controller_t* pWanController) +{ + DML_WAN_IFACE* pActiveInterface = NULL; + int newPrimaryInterface = -1; + int newSecondaryInterface = -1; + + if(pWanController == NULL) + { + CcspTraceError(("%s %d pWanController object is NULL \n", __FUNCTION__, __LINE__)); + return ANSC_STATUS_FAILURE; + } + + if(pWanController->pWanActiveIfaceData == NULL) + { + return STATE_INTERFACE_DOWN; + } + + pActiveInterface = &(pWanController->pWanActiveIfaceData->data); + + + if( pWanController->WanEnable == FALSE || + pActiveInterface->Phy.Status == WAN_IFACE_PHY_STATUS_DOWN || + pActiveInterface->Wan.Type != WAN_IFACE_TYPE_PRIMARY || + pActiveInterface->Wan.Enable == FALSE) + { + return Transition_PrimaryInterfaceDeSelected(pWanController); + } + + + //Check interface config/status changes + WanMgr_Policy_FM_SelectWANActive(pWanController, &newPrimaryInterface, &newSecondaryInterface); + + if(newPrimaryInterface != pWanController->activeInterfaceIdx) + { + return Transition_PrimaryInterfaceDeSelected(pWanController); + } + +#ifdef WAN_ENABLE_STANDBY + if(newSecondaryInterface != pWanController->selSecondaryInterfaceIdx) + { + pWanController->selSecondaryInterfaceIdx = newSecondaryInterface; + return Transition_SecondaryInterfaceUp(pWanController); + } +#endif //WAN_ENABLE_STANDBY + + return STATE_PRIMARY_WAN_ACTIVE; +} + +static WcPpPolicyState_t State_SecondaryWanActive(WanMgr_Policy_Controller_t* pWanController) +{ + DML_WAN_IFACE* pActiveInterface = NULL; + int newPrimaryInterface = -1; + int newSecondaryInterface = -1; + + if(pWanController == NULL) + { + CcspTraceError(("%s %d pWanController object is NULL \n", __FUNCTION__, __LINE__)); + return ANSC_STATUS_FAILURE; + } + + if(pWanController->pWanActiveIfaceData == NULL) + { + return STATE_INTERFACE_DOWN; + } + + pActiveInterface = &(pWanController->pWanActiveIfaceData->data); + + + if( pWanController->WanEnable == FALSE || + pActiveInterface->Phy.Status == WAN_IFACE_PHY_STATUS_DOWN || + pActiveInterface->Wan.Type != WAN_IFACE_TYPE_SECONDARY || + pActiveInterface->Wan.Enable == FALSE) + { + return Transition_SecondaryInterfaceDeSelected(pWanController); + } + + + //Check interface config/status changes + WanMgr_Policy_FM_SelectWANActive(pWanController, &newPrimaryInterface, &newSecondaryInterface); + + if( newSecondaryInterface != pWanController->activeInterfaceIdx ) + { + return Transition_SecondaryInterfaceDeSelected(pWanController); + } + + if( newPrimaryInterface != -1 ) + { +#ifdef WAN_ENABLE_STANDBY + pWanController->activeInterfaceIdx = newPrimaryInterface; + return Transition_PrimaryInterfaceSelected(pWanController); +#else + return Transition_SecondaryInterfaceDeSelected(pWanController); +#endif + } + + return STATE_SECONDARY_WAN_ACTIVE; +} + +static WcPpPolicyState_t State_PrimaryWanActiveSecondaryWanUp(WanMgr_Policy_Controller_t* pWanController) +{ + DML_WAN_IFACE* pActiveInterface = NULL; + int newPrimaryInterface = -1; + int newSecondaryInterface = -1; + + if(pWanController == NULL) + { + CcspTraceError(("%s %d pWanController object is NULL \n", __FUNCTION__, __LINE__)); + return ANSC_STATUS_FAILURE; + } + + if(pWanController->pWanActiveIfaceData == NULL) + { + return STATE_INTERFACE_DOWN; + } + + pActiveInterface = &(pWanController->pWanActiveIfaceData->data); + + /* Phy.Status of the Active Primary Interface is DOWN, or Wan.Enable of the Active Primary Interface + is FALSE, or Wan.Type of the Active Primary Interface is not PRIMARY, or Global Enable is FALSE */ + if (pWanController->WanEnable != TRUE || + pActiveInterface->Wan.Enable != TRUE || + pActiveInterface->Wan.Type != WAN_IFACE_TYPE_PRIMARY || + pActiveInterface->Phy.Status == WAN_IFACE_PHY_STATUS_DOWN) + { + return Transition_SecondaryInterfaceSelected(pWanController); + } + + //Check interface config/status changes + WanMgr_Policy_FM_SelectWANActive(pWanController, &newPrimaryInterface, &newSecondaryInterface); + + /* Check any new Primary Interfaces is up */ + if(newPrimaryInterface != pWanController->activeInterfaceIdx) + { + return Transition_PrimaryInterfaceChanged(pWanController); + } + + /* If all Secondary Interfaces are set to DISABLED */ + if(newSecondaryInterface == -1) + { + return Transition_SecondaryInterfaceDown(pWanController); + } + + /* Check any new Secondary Interfaces is up */ + if(newSecondaryInterface != pWanController->selSecondaryInterfaceIdx) + { + pWanController->selSecondaryInterfaceIdx = newSecondaryInterface; + return Transition_SecondaryInterfaceUp(pWanController); + } + + return STATE_PRIMARY_WAN_ACTIVE_SECONDARY_WAN_UP; +} + + +/*********************************************************************************/ +/*********************************************************************************/ +/*********************************************************************************/ +/* WanMgr_Policy_PrimaryPriorityPolicy */ +ANSC_STATUS WanMgr_Policy_PrimaryPriorityPolicy(void) +{ + CcspTraceInfo(("%s %d \n", __FUNCTION__, __LINE__)); + + //detach thread from caller stack + pthread_detach(pthread_self()); + + //policy variables + ANSC_STATUS retStatus = ANSC_STATUS_SUCCESS; + WanMgr_Policy_Controller_t WanPolicyCtrl; + WcPpPolicyState_t pp_sm_state; + bool bRunning = true; + + // event handler + int n = 0; + struct timeval tv; + + if(WanMgr_Controller_PolicyCtrlInit(&WanPolicyCtrl) != ANSC_STATUS_SUCCESS) + { + CcspTraceError(("%s %d Policy Controller Error \n", __FUNCTION__, __LINE__)); + return ANSC_STATUS_FAILURE; + } + + CcspTraceInfo(("%s %d Primary Priority Policy Thread Starting \n", __FUNCTION__, __LINE__)); + + // initialise state machine + pp_sm_state = Transition_Start(&WanPolicyCtrl); // do this first before anything else to init variables + + while (bRunning) + { + /* Wait up to 500 milliseconds */ + tv.tv_sec = 0; + tv.tv_usec = LOOP_TIMEOUT; + + n = select(0, NULL, NULL, NULL, &tv); + if (n < 0) + { + /* interrupted by signal or something, continue */ + continue; + } + + //Update Wan config + WanMgr_Config_Data_t* pWanConfigData = WanMgr_GetConfigData_locked(); + if(pWanConfigData != NULL) + { + WanPolicyCtrl.WanEnable = pWanConfigData->data.Enable; + + WanMgrDml_GetConfigData_release(pWanConfigData); + } + + //Lock Iface Data + WanPolicyCtrl.pWanActiveIfaceData = WanMgr_GetIfaceData_locked(WanPolicyCtrl.activeInterfaceIdx); + + // process state + switch (pp_sm_state) + { + case STATE_INTERFACE_DOWN: + pp_sm_state = State_WanDown(&WanPolicyCtrl); + break; + case STATE_PRIMARY_WAN_ACTIVE: + pp_sm_state = State_PrimaryWanActive(&WanPolicyCtrl); + break; + case STATE_SECONDARY_WAN_ACTIVE: + pp_sm_state = State_SecondaryWanActive(&WanPolicyCtrl); + break; + case STATE_PRIMARY_WAN_ACTIVE_SECONDARY_WAN_UP: + pp_sm_state = State_PrimaryWanActiveSecondaryWanUp(&WanPolicyCtrl); + break; + default: + CcspTraceInfo(("%s %d - Case: default \n", __FUNCTION__, __LINE__)); + bRunning = false; + retStatus = ANSC_STATUS_FAILURE; + break; + } + + //Release Lock Iface Data + if(WanPolicyCtrl.pWanActiveIfaceData != NULL) + { + WanMgrDml_GetIfaceData_release(WanPolicyCtrl.pWanActiveIfaceData); + } + } + + CcspTraceInfo(("%s %d - Exit from state machine\n", __FUNCTION__, __LINE__)); + return retStatus; +} diff --git a/source/WanManager/wanmgr_policy_ppob_impl.c b/source/WanManager/wanmgr_policy_ppob_impl.c new file mode 100644 index 00000000..4ef41953 --- /dev/null +++ b/source/WanManager/wanmgr_policy_ppob_impl.c @@ -0,0 +1,421 @@ +/* + If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2019 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +/* ---- Include Files ---------------------------------------- */ +#include +#include +#include +#include +#include "wanmgr_controller.h" +#include "wanmgr_data.h" +#include "wanmgr_rdkbus_utils.h" +#include "wanmgr_interface_sm.h" +#include "wanmgr_platform_events.h" + +/* ---- Global Constants -------------------------- */ +#define LOOP_TIMEOUT 500000 // timeout in milliseconds. This is the state machine loop interval + +typedef enum { + SELECTING_WAN_INTERFACE = 0, + SELECTED_INTERFACE_DOWN, + SELECTED_INTERFACE_UP +} WcPpobPolicyState_t; + + +/* STATES */ +static WcPpobPolicyState_t State_SelectingWanInterface(WanMgr_Policy_Controller_t* pWanController); +static WcPpobPolicyState_t State_SelectedInterfaceDown(WanMgr_Policy_Controller_t* pWanController); +static WcPpobPolicyState_t State_SelectedInterfaceUp(WanMgr_Policy_Controller_t* pWanController); + +/* TRANSITIONS */ +static WcPpobPolicyState_t Transition_Start(WanMgr_Policy_Controller_t* pWanController); +static WcPpobPolicyState_t Transition_WanInterfaceSelected(WanMgr_Policy_Controller_t* pWanController); +static WcPpobPolicyState_t Transition_SelectedInterfaceUp(WanMgr_Policy_Controller_t* pWanController); +static WcPpobPolicyState_t Transition_SelectedInterfaceDown(WanMgr_Policy_Controller_t* pWanController); + +/*********************************************************************************/ +/**************************** ACTIONS ********************************************/ +/*********************************************************************************/ +static void WanMgr_Policy_FM_SelectWANActive(WanMgr_Policy_Controller_t* pWanController, INT* pPrimaryInterface, INT* pSecondaryInterface) +{ + UINT uiLoopCount; + UINT uiTotalIfaces = -1; + INT iSelPrimaryInterface = -1; + INT iSelSecondaryInterface = -1; + INT iSelPrimaryPriority = DML_WAN_IFACE_PRIORITY_MAX; + INT iSelSecondaryPriority = DML_WAN_IFACE_PRIORITY_MAX; + + //Get uiTotalIfaces + WanMgr_IfaceCtrl_Data_t* pWanIfaceCtrl = WanMgr_GetIfaceCtrl_locked(); + if(pWanIfaceCtrl != NULL) + { + uiTotalIfaces = pWanIfaceCtrl->ulTotalNumbWanInterfaces; + + WanMgrDml_GetIfaceCtrl_release(pWanIfaceCtrl); + } + + if(uiTotalIfaces > 0) + { + // Check the policy to determine if any primary interface should be used for WAN + if(pWanController->WanEnable == TRUE) + { + for( uiLoopCount = 0; uiLoopCount < uiTotalIfaces; uiLoopCount++ ) + { + + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(uiLoopCount); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanIfaceData = &(pWanDmlIfaceData->data); + + if (pWanIfaceData->Wan.Enable == TRUE && + (pWanIfaceData->Phy.Status == WAN_IFACE_PHY_STATUS_UP || + pWanIfaceData->Phy.Status == WAN_IFACE_PHY_STATUS_INITIALIZING)) + { + if(pWanIfaceData->Wan.Type == WAN_IFACE_TYPE_PRIMARY) + { + if(pWanIfaceData->Wan.Priority < iSelPrimaryPriority) + { + if(pWanIfaceData->Wan.Priority >= 0) + { + iSelPrimaryInterface = uiLoopCount; + iSelPrimaryPriority = pWanIfaceData->Wan.Priority; + } + } + } + else + { + if(pWanIfaceData->Wan.Priority < iSelSecondaryPriority) + { + if(pWanIfaceData->Wan.Priority >= 0) + { + iSelSecondaryInterface = uiLoopCount; + iSelSecondaryPriority = pWanIfaceData->Wan.Priority; + } + } + } + } + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + } + } + } + + *pPrimaryInterface = iSelPrimaryInterface; + *pSecondaryInterface = iSelSecondaryInterface; + + return ; +} + + +/*********************************************************************************/ +/************************** TRANSITIONS ******************************************/ +/*********************************************************************************/ +static WcPpobPolicyState_t Transition_Start(WanMgr_Policy_Controller_t* pWanController) +{ + if(pWanController == NULL) + { + return ANSC_STATUS_FAILURE; + } + + WanMgr_UpdatePlatformStatus(WANMGR_DISCONNECTED); + + return SELECTING_WAN_INTERFACE; +} + +static WcPpobPolicyState_t Transition_WanInterfaceSelected(WanMgr_Policy_Controller_t* pWanController) +{ + DML_WAN_IFACE* pActiveInterface = NULL; + bool bWanActive = false; + WanMgr_IfaceSM_Controller_t wanIfCtrl; + + if(pWanController == NULL) + { + CcspTraceError(("%s %d pWanController object is NULL \n", __FUNCTION__, __LINE__)); + return ANSC_STATUS_FAILURE; + } + + + /* Select WAN as Active */ + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pWanController->activeInterfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanIfaceData = &(pWanDmlIfaceData->data); + + //Set ActiveLink to TRUE + pWanIfaceData->Wan.ActiveLink = TRUE; + bWanActive = true; + + WanMgr_IfaceSM_Init(&wanIfCtrl, pWanIfaceData->uiIfaceIdx); + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + + if(bWanActive == false) + { + return SELECTED_INTERFACE_DOWN; + } + + WanMgr_UpdatePlatformStatus(WANMGR_CONNECTING); + + /* Starts an instance of the WAN Interface State Machine on + the interface to begin configuring the WAN link */ + WanMgr_StartInterfaceStateMachine(&wanIfCtrl); + + return SELECTED_INTERFACE_UP; +} + +static WcPpobPolicyState_t Transition_SelectedInterfaceUp(WanMgr_Policy_Controller_t* pWanController) +{ + DML_WAN_IFACE* pActiveInterface = NULL; + bool bWanActive = false; + WanMgr_IfaceSM_Controller_t wanIfCtrl; + + if(pWanController == NULL) + { + CcspTraceError(("%s %d pWanController object is NULL \n", __FUNCTION__, __LINE__)); + return ANSC_STATUS_FAILURE; + } + + /* Cheack Active WAN is present */ + WanMgr_Iface_Data_t* pWanDmlIfaceData = WanMgr_GetIfaceData_locked(pWanController->activeInterfaceIdx); + if(pWanDmlIfaceData != NULL) + { + DML_WAN_IFACE* pWanIfaceData = &(pWanDmlIfaceData->data); + + WanMgr_IfaceSM_Init(&wanIfCtrl, pWanIfaceData->uiIfaceIdx); + + bWanActive = true; + + WanMgrDml_GetIfaceData_release(pWanDmlIfaceData); + } + + if(bWanActive == false) + { + return ANSC_STATUS_FAILURE; + } + + + WanMgr_UpdatePlatformStatus(WANMGR_CONNECTING); + + /* Starts an instance of the WAN Interface State Machine on + the interface to begin configuring the WAN link */ + WanMgr_StartInterfaceStateMachine(&wanIfCtrl); + + return SELECTED_INTERFACE_UP; +} + +static WcPpobPolicyState_t Transition_SelectedInterfaceDown(WanMgr_Policy_Controller_t* pWanController) +{ + WanMgr_UpdatePlatformStatus(WANMGR_DISCONNECTED); + return SELECTED_INTERFACE_DOWN; +} + +/*********************************************************************************/ +/**************************** STATES *********************************************/ +/*********************************************************************************/ +static WcPpobPolicyState_t State_SelectingWanInterface(WanMgr_Policy_Controller_t* pWanController) +{ + int selectedPrimaryInterface = -1; + int selectedSecondaryInterface = -1; + + if(pWanController == NULL) + { + CcspTraceError(("%s %d pWanController object is NULL \n", __FUNCTION__, __LINE__)); + return ANSC_STATUS_FAILURE; + } + + WanMgr_Policy_FM_SelectWANActive(pWanController, &selectedPrimaryInterface, &selectedSecondaryInterface); + + + if(selectedPrimaryInterface != -1 && selectedSecondaryInterface != -1) + { + /* multiple interfaces connected, so start selectiontimeout timer + if selectiontimeout timer > maximum selection timeout of the connected interfaces, + use the highest priority interface */ + pWanController->activeInterfaceIdx = selectedPrimaryInterface; + } + else if(selectedPrimaryInterface != -1) + { + pWanController->activeInterfaceIdx = selectedPrimaryInterface; + } + else if(selectedSecondaryInterface != -1) + { + pWanController->activeInterfaceIdx = selectedSecondaryInterface; + } + + if(pWanController->activeInterfaceIdx != -1) + { + return Transition_WanInterfaceSelected(pWanController); + } + + return SELECTING_WAN_INTERFACE; +} + +static WcPpobPolicyState_t State_SelectedInterfaceUp(WanMgr_Policy_Controller_t* pWanController) +{ + DML_WAN_IFACE* pActiveInterface = NULL; + + if(pWanController == NULL) + { + CcspTraceError(("%s %d pWanController object is NULL \n", __FUNCTION__, __LINE__)); + return ANSC_STATUS_FAILURE; + } + + if(pWanController->pWanActiveIfaceData == NULL) + { + return SELECTED_INTERFACE_DOWN; + } + + pActiveInterface = &(pWanController->pWanActiveIfaceData->data); + + + if( pWanController->WanEnable == FALSE || + pActiveInterface->Phy.Status == WAN_IFACE_PHY_STATUS_DOWN || + pActiveInterface->Wan.Enable == FALSE) + { + return Transition_SelectedInterfaceDown(pWanController); + } + + /* TODO: Traffic to the WAN Interface has been idle for a time that exceeds + the configured IdleTimeout value */ + //return Transition_SelectedInterfaceDown(pWanController); + + return SELECTED_INTERFACE_UP; +} + +static WcPpobPolicyState_t State_SelectedInterfaceDown(WanMgr_Policy_Controller_t* pWanController) +{ + DML_WAN_IFACE* pActiveInterface = NULL; + + if(pWanController == NULL) + { + CcspTraceError(("%s %d pWanController object is NULL \n", __FUNCTION__, __LINE__)); + return ANSC_STATUS_FAILURE; + } + + if(pWanController->pWanActiveIfaceData == NULL) + { + return SELECTED_INTERFACE_DOWN; + } + + pActiveInterface = &(pWanController->pWanActiveIfaceData->data); + + if(pWanController->WanEnable == TRUE && + (pActiveInterface->Phy.Status == WAN_IFACE_PHY_STATUS_UP || + pActiveInterface->Phy.Status == WAN_IFACE_PHY_STATUS_INITIALIZING) && + pActiveInterface->Wan.LinkStatus == WAN_IFACE_LINKSTATUS_DOWN && + pActiveInterface->Wan.Status == WAN_IFACE_STATUS_DISABLED) + { + return Transition_SelectedInterfaceUp(pWanController); + } + + return SELECTED_INTERFACE_DOWN; +} + + +/*********************************************************************************/ +/*********************************************************************************/ +/*********************************************************************************/ +/* WanMgr_Policy_PrimaryPriorityOnBootupPolicy */ +ANSC_STATUS WanMgr_Policy_PrimaryPriorityOnBootupPolicy(void) +{ + CcspTraceInfo(("%s %d \n", __FUNCTION__, __LINE__)); + + //detach thread from caller stack + pthread_detach(pthread_self()); + + //policy variables + ANSC_STATUS retStatus = ANSC_STATUS_SUCCESS; + WanMgr_Policy_Controller_t WanPolicyCtrl; + WcPpobPolicyState_t ppob_sm_state; + bool bRunning = true; + + // event handler + int n = 0; + struct timeval tv; + + + if(WanMgr_Controller_PolicyCtrlInit(&WanPolicyCtrl) != ANSC_STATUS_SUCCESS) + { + CcspTraceError(("%s %d Policy Controller Error \n", __FUNCTION__, __LINE__)); + return ANSC_STATUS_FAILURE; + } + + CcspTraceInfo(("%s %d Primary Priority On Bootup Policy Thread Starting \n", __FUNCTION__, __LINE__)); + + // initialise state machine + ppob_sm_state = Transition_Start(&WanPolicyCtrl); // do this first before anything else to init variables + + while (bRunning) + { + /* Wait up to 500 milliseconds */ + tv.tv_sec = 0; + tv.tv_usec = LOOP_TIMEOUT; + + n = select(0, NULL, NULL, NULL, &tv); + if (n < 0) + { + /* interrupted by signal or something, continue */ + continue; + } + + //Update Wan config + WanMgr_Config_Data_t* pWanConfigData = WanMgr_GetConfigData_locked(); + if(pWanConfigData != NULL) + { + WanPolicyCtrl.WanEnable = pWanConfigData->data.Enable; + + WanMgrDml_GetConfigData_release(pWanConfigData); + } + + //Lock Iface Data + WanPolicyCtrl.pWanActiveIfaceData = WanMgr_GetIfaceData_locked(WanPolicyCtrl.activeInterfaceIdx); + + // process state + switch (ppob_sm_state) + { + case SELECTING_WAN_INTERFACE: + ppob_sm_state = State_SelectingWanInterface(&WanPolicyCtrl); + break; + case SELECTED_INTERFACE_DOWN: + ppob_sm_state = State_SelectedInterfaceDown(&WanPolicyCtrl); + break; + case SELECTED_INTERFACE_UP: + ppob_sm_state = State_SelectedInterfaceUp(&WanPolicyCtrl); + break; + default: + CcspTraceInfo(("%s %d - Case: default \n", __FUNCTION__, __LINE__)); + bRunning = false; + retStatus = ANSC_STATUS_FAILURE; + break; + } + + //Release Lock Iface Data + if(WanPolicyCtrl.pWanActiveIfaceData != NULL) + { + WanMgrDml_GetIfaceData_release(WanPolicyCtrl.pWanActiveIfaceData); + } + } + + CcspTraceInfo(("%s %d - Exit from state machine\n", __FUNCTION__, __LINE__)); + + return retStatus; +} + diff --git a/source/WanManager/wanmgr_ssp_action.c b/source/WanManager/wanmgr_ssp_action.c new file mode 100644 index 00000000..7df19666 --- /dev/null +++ b/source/WanManager/wanmgr_ssp_action.c @@ -0,0 +1,353 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2017 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ +/********************************************************************** + Copyright [2014] [Cisco Systems, Inc.] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +**********************************************************************/ + +/********************************************************************************* + + description: + + This is the template file of ssp_action.c for XxxxSsp. + Please replace "XXXX" with your own ssp name with the same up/lower cases. + + SSP implementation of functions: + + * ssp_create + * ssp_engage + * ssp_cancel + * ssp_CcdIfGetComponentName + * ssp_CcdIfGetComponentVersion + * ssp_CcdIfGetComponentAuthor + * ssp_CcdIfGetComponentHealth + * ssp_CcdIfGetComponentState + * ssp_CcdIfGetLoggingEnabled + * ssp_CcdIfSetLoggingEnabled + * ssp_CcdIfGetLoggingLevel + * ssp_CcdIfSetLoggingLevel + * ssp_CcdIfGetMemMaxUsage + * ssp_CcdIfGetMemMinUsage + * ssp_CcdIfGetMemConsumed + + ------------------------------------------------------------------------------ + + revision: + + 09/08/2011 initial revision. + +**********************************************************************************/ + +#include "wanmgr_ssp_global.h" +#include "wanmgr_plugin_main.h" +#include "dslh_dmagnt_interface.h" +#include "ccsp_trace.h" + + +#define DATAMODEL_XML_FILE "/usr/rdk/wanmanager/RdkWanManager.xml" + + +PDSLH_CPE_CONTROLLER_OBJECT pDslhCpeController = NULL; +PCOMPONENT_COMMON_WANMANAGER g_pComponent_COMMON_wanmanager = NULL; +PCCSP_CCD_INTERFACE pSsdCcdIf = (PCCSP_CCD_INTERFACE )NULL; +PDSLH_LCB_INTERFACE pDslhLcbIf = (PDSLH_LCB_INTERFACE )NULL; +extern char g_Subsystem[32]; + + +extern ANSC_HANDLE bus_handle; +extern ULONG g_ulAllocatedSizePeak; + +ANSC_STATUS ssp_create() +{ + /* Create component common data model object */ + + g_pComponent_COMMON_wanmanager = (PCOMPONENT_COMMON_WANMANAGER)AnscAllocateMemory(sizeof(COMPONENT_COMMON_WANMANAGER)); + + if ( ! g_pComponent_COMMON_wanmanager ) + { + return ANSC_STATUS_RESOURCES; + } + + ComponentCommonDmInit( g_pComponent_COMMON_wanmanager); + + g_pComponent_COMMON_wanmanager->Name = AnscCloneString(COMPONENT_NAME_WANMANAGER); + g_pComponent_COMMON_wanmanager->Version = 1; + g_pComponent_COMMON_wanmanager->Author = AnscCloneString("Your name"); + + /* Create ComponentCommonDatamodel interface*/ + if ( !pSsdCcdIf ) + { + pSsdCcdIf = (PCCSP_CCD_INTERFACE)AnscAllocateMemory(sizeof(CCSP_CCD_INTERFACE)); + + if ( !pSsdCcdIf ) + { + return ANSC_STATUS_RESOURCES; + } + else + { + AnscCopyString(pSsdCcdIf->Name, CCSP_CCD_INTERFACE_NAME); + + pSsdCcdIf->InterfaceId = CCSP_CCD_INTERFACE_ID; + pSsdCcdIf->hOwnerContext = NULL; + pSsdCcdIf->Size = sizeof(CCSP_CCD_INTERFACE); + + pSsdCcdIf->GetComponentName = ssp_CcdIfGetComponentName; + pSsdCcdIf->GetComponentVersion = ssp_CcdIfGetComponentVersion; + pSsdCcdIf->GetComponentAuthor = ssp_CcdIfGetComponentAuthor; + pSsdCcdIf->GetComponentHealth = ssp_CcdIfGetComponentHealth; + pSsdCcdIf->GetComponentState = ssp_CcdIfGetComponentState; + pSsdCcdIf->GetLoggingEnabled = ssp_CcdIfGetLoggingEnabled; + pSsdCcdIf->SetLoggingEnabled = ssp_CcdIfSetLoggingEnabled; + pSsdCcdIf->GetLoggingLevel = ssp_CcdIfGetLoggingLevel; + pSsdCcdIf->SetLoggingLevel = ssp_CcdIfSetLoggingLevel; + pSsdCcdIf->GetMemMaxUsage = ssp_CcdIfGetMemMaxUsage; + pSsdCcdIf->GetMemMinUsage = ssp_CcdIfGetMemMinUsage; + pSsdCcdIf->GetMemConsumed = ssp_CcdIfGetMemConsumed; + pSsdCcdIf->ApplyChanges = ssp_CcdIfApplyChanges; + } + } + + /* Create ComponentCommonDatamodel interface*/ + if ( !pDslhLcbIf ) + { + pDslhLcbIf = (PDSLH_LCB_INTERFACE)AnscAllocateMemory(sizeof(DSLH_LCB_INTERFACE)); + + if ( !pDslhLcbIf ) + { + return ANSC_STATUS_RESOURCES; + } + else + { + AnscCopyString(pDslhLcbIf->Name, CCSP_LIBCBK_INTERFACE_NAME); + + pDslhLcbIf->InterfaceId = CCSP_LIBCBK_INTERFACE_ID; + pDslhLcbIf->hOwnerContext = NULL; + pDslhLcbIf->Size = sizeof(DSLH_LCB_INTERFACE); + + pDslhLcbIf->InitLibrary = WanManagerDmlInit; + } + } + + pDslhCpeController = DslhCreateCpeController(NULL, NULL, NULL); + + if ( !pDslhCpeController ) + { + CcspTraceWarning(("CANNOT Create pDslhCpeController... Exit!\n")); + + return ANSC_STATUS_RESOURCES; + } + + return ANSC_STATUS_SUCCESS; +} + +ANSC_STATUS ssp_engage() +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + PCCC_MBI_INTERFACE pSsdMbiIf = (PCCC_MBI_INTERFACE)MsgHelper_CreateCcdMbiIf((void*)bus_handle, g_Subsystem); + char CrName[256]; + + g_pComponent_COMMON_wanmanager->Health = COMMON_COMPONENT_HEALTH_Yellow; + + /* data model configuration */ + pDslhCpeController->AddInterface((ANSC_HANDLE)pDslhCpeController, (ANSC_HANDLE)pDslhLcbIf); + pDslhCpeController->AddInterface((ANSC_HANDLE)pDslhCpeController, (ANSC_HANDLE)pSsdMbiIf); + pDslhCpeController->AddInterface((ANSC_HANDLE)pDslhCpeController, (ANSC_HANDLE)pSsdCcdIf); + pDslhCpeController->SetDbusHandle((ANSC_HANDLE)pDslhCpeController, (ANSC_HANDLE)bus_handle); + pDslhCpeController->Engage((ANSC_HANDLE)pDslhCpeController); + + if ( g_Subsystem[0] != 0 ) + { + _ansc_sprintf(CrName, "%s%s", g_Subsystem, CCSP_DBUS_INTERFACE_CR); + } + else + { + _ansc_sprintf(CrName, "%s", CCSP_DBUS_INTERFACE_CR); + } + + returnStatus = + pDslhCpeController->RegisterCcspDataModel + ( + (ANSC_HANDLE)pDslhCpeController, + CrName, /* CCSP_DBUS_INTERFACE_CR,*/ /* CCSP CR ID */ + DATAMODEL_XML_FILE, /* Data Model XML file. Can be empty if only base data model supported. */ + COMPONENT_NAME_WANMANAGER, /* Component Name */ + COMPONENT_VERSION_WANMANAGER, /* Component Version */ + COMPONENT_PATH_WANMANAGER, /* Component Path */ + g_Subsystem /* Component Prefix */ + ); + + if ( returnStatus == ANSC_STATUS_SUCCESS ) + { + /* System is fully initialized */ + g_pComponent_COMMON_wanmanager->Health = COMMON_COMPONENT_HEALTH_Green; + } + + return ANSC_STATUS_SUCCESS; +} + + +ANSC_STATUS ssp_cancel() +{ + int nRet = 0; + char CrName[256]; + char CpName[256]; + + if( g_pComponent_COMMON_wanmanager == NULL) + { + return ANSC_STATUS_SUCCESS; + } + + if ( g_Subsystem[0] != 0 ) + { + _ansc_sprintf(CrName, "%s%s", g_Subsystem, CCSP_DBUS_INTERFACE_CR); + _ansc_sprintf(CpName, "%s%s", g_Subsystem, COMPONENT_NAME_WANMANAGER); + } + else + { + _ansc_sprintf(CrName, "%s", CCSP_DBUS_INTERFACE_CR); + _ansc_sprintf(CpName, "%s", COMPONENT_NAME_WANMANAGER); + } + /* unregister component */ + nRet = CcspBaseIf_unregisterComponent(bus_handle, CrName, CpName ); + AnscTrace("unregisterComponent returns %d\n", nRet); + + pDslhCpeController->Cancel((ANSC_HANDLE)pDslhCpeController); + AnscFreeMemory(pDslhCpeController); + + if ( pSsdCcdIf ) AnscFreeMemory(pSsdCcdIf); + if ( g_pComponent_COMMON_wanmanager ) AnscFreeMemory( g_pComponent_COMMON_wanmanager); + + g_pComponent_COMMON_wanmanager = NULL; + pSsdCcdIf = NULL; + pDslhCpeController = NULL; + + return ANSC_STATUS_SUCCESS; +} + + +char* ssp_CcdIfGetComponentName(ANSC_HANDLE hThisObject) +{ + return g_pComponent_COMMON_wanmanager->Name; +} + + +ULONG ssp_CcdIfGetComponentVersion(ANSC_HANDLE hThisObject) +{ + return g_pComponent_COMMON_wanmanager->Version; +} + + +char* ssp_CcdIfGetComponentAuthor(ANSC_HANDLE hThisObject) +{ + return g_pComponent_COMMON_wanmanager->Author; +} + + +ULONG ssp_CcdIfGetComponentHealth(ANSC_HANDLE hThisObject) +{ + return g_pComponent_COMMON_wanmanager->Health; +} + + +ULONG ssp_CcdIfGetComponentState(ANSC_HANDLE hThisObject) +{ + return g_pComponent_COMMON_wanmanager->State; +} + + + +BOOL ssp_CcdIfGetLoggingEnabled(ANSC_HANDLE hThisObject) +{ + return g_pComponent_COMMON_wanmanager->LogEnable; +} + + +ANSC_STATUS +ssp_CcdIfSetLoggingEnabled(ANSC_HANDLE hThisObject, BOOL bEnabled) +{ + if( g_pComponent_COMMON_wanmanager->LogEnable == bEnabled) return ANSC_STATUS_SUCCESS; + g_pComponent_COMMON_wanmanager->LogEnable = bEnabled; + if(bEnabled) g_iTraceLevel = (INT) g_pComponent_COMMON_wanmanager->LogLevel; + else g_iTraceLevel = CCSP_TRACE_INVALID_LEVEL; + + return ANSC_STATUS_SUCCESS; +} + + +ULONG ssp_CcdIfGetLoggingLevel(ANSC_HANDLE hThisObject) +{ + return g_pComponent_COMMON_wanmanager->LogLevel; +} + + +ANSC_STATUS ssp_CcdIfSetLoggingLevel(ANSC_HANDLE hThisObject, ULONG LogLevel) +{ + if( g_pComponent_COMMON_wanmanager->LogLevel == LogLevel) return ANSC_STATUS_SUCCESS; + g_pComponent_COMMON_wanmanager->LogLevel = LogLevel; + if( g_pComponent_COMMON_wanmanager->LogEnable) g_iTraceLevel = (INT) g_pComponent_COMMON_wanmanager->LogLevel; + + return ANSC_STATUS_SUCCESS; +} + + +ULONG ssp_CcdIfGetMemMaxUsage(ANSC_HANDLE hThisObject) +{ + return g_ulAllocatedSizePeak; +} + + +ULONG ssp_CcdIfGetMemMinUsage(ANSC_HANDLE hThisObject) +{ + return g_pComponent_COMMON_wanmanager->MemMinUsage; +} + + +ULONG +ssp_CcdIfGetMemConsumed(ANSC_HANDLE hThisObject) +{ + LONG size = 0; + + size = AnscGetComponentMemorySize(COMPONENT_NAME_WANMANAGER); + if (size == -1 ) + size = 0; + + return size; +} + + +ANSC_STATUS +ssp_CcdIfApplyChanges(ANSC_HANDLE hThisObject) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + /* Assume the parameter settings are committed immediately. */ + /* AnscSetTraceLevel((INT) g_pComponent_COMMON_wanmanager->LogLevel); */ + + return returnStatus; +} diff --git a/source/WanManager/wanmgr_ssp_global.h b/source/WanManager/wanmgr_ssp_global.h new file mode 100644 index 00000000..e0ab0d18 --- /dev/null +++ b/source/WanManager/wanmgr_ssp_global.h @@ -0,0 +1,74 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2017 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +/********************************************************************************* + + description: + + This is the template file of wanmgr_ssp_global.h for XxxxSsp. + You may add the header files you want to include. + + ------------------------------------------------------------------------------ + + revision: + + 09/08/2011 initial revision. + +**********************************************************************************/ + +#ifndef _WANMGR_SSP_GLOBAL_H +#define _WANMGR_SSP_GLOBAL_H + +#include + +#include "ansc_platform.h" +#include "slap_definitions.h" + +#ifndef WIN32 +#include "ccsp_message_bus.h" +#endif + +#include "ccsp_base_api.h" + +#include "dslh_cpeco_interface.h" +#include "dslh_cpeco_exported_api.h" + +#include "slap_vco_exported_api.h" +#include "wanmgr_ssp_messagebus_interface.h" + +#include "dslh_ifo_mpa.h" +#include "dslh_dmagnt_interface.h" +#include "dslh_dmagnt_exported_api.h" + +#include "wanmgr_ssp_internal.h" +#include "ccsp_ifo_ccd.h" +#include "ccc_ifo_mbi.h" + +#include "messagebus_interface_helper.h" + +/* + * Define custom trace module ID + */ +#ifdef ANSC_TRACE_MODULE_ID + #undef ANSC_TRACE_MODULE_ID +#endif + +#define ANSC_TRACE_MODULE_ID ANSC_TRACE_ID_SSP + +#endif //_WANMGR_SSP_GLOBAL_H diff --git a/source/WanManager/wanmgr_ssp_internal.h b/source/WanManager/wanmgr_ssp_internal.h new file mode 100644 index 00000000..2db429ea --- /dev/null +++ b/source/WanManager/wanmgr_ssp_internal.h @@ -0,0 +1,137 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2017 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + + +/********************************************************************************* + + description: + + This is the template file of wanmgr_ssp_internal.h for XxxxSsp. + Please replace "XXXX" with your own ssp name with the same up/lower cases. + + ------------------------------------------------------------------------------ + + revision: + + 09/08/2011 initial revision. + +**********************************************************************************/ + +#ifndef _WANMGR_SSP_INTERNAL_H_ +#define _WANMGR_SSP_INTERNAL_H_ + +#define COMMON_COMPONENT_HEALTH_Red 1 +#define COMMON_COMPONENT_HEALTH_Yellow 2 +#define COMMON_COMPONENT_HEALTH_Green 3 + +#define COMMON_COMPONENT_STATE_Initializing 1 +#define COMMON_COMPONENT_STATE_Running 2 +#define COMMON_COMPONENT_STATE_Blocked 3 +#define COMMON_COMPONENT_STATE_Paused 3 + +#define COMMON_COMPONENT_FREERESOURCES_PRIORITY_High 1 +#define COMMON_COMPONENT_FREERESOURCES_PRIORITY_Low 2 + +#define COMPONENT_ID_WANMANAGER "com.cisco.spvtg.ccsp.wanmanager" +#define COMPONENT_NAME_WANMANAGER "com.cisco.spvtg.ccsp.wanmanager" +#define COMPONENT_VERSION_WANMANAGER 1 +#define COMPONENT_PATH_WANMANAGER "/com/cisco/spvtg/ccsp/wanmanager" +#define WAN_COMPONENT_NAME "eRT.com.cisco.spvtg.ccsp.wanmanager" + +#define MESSAGE_BUS_CONFIG_FILE "msg_daemon.cfg" + +typedef struct _COMPONENT_COMMON_WANMANAGER +{ + char* Name; + ULONG Version; + char* Author; + ULONG Health; + ULONG State; + + BOOL LogEnable; + ULONG LogLevel; + + ULONG MemMaxUsage; + ULONG MemMinUsage; + ULONG MemConsumed; +} COMPONENT_COMMON_WANMANAGER, *PCOMPONENT_COMMON_WANMANAGER; + +#define ComponentCommonDmInit(component_com_wanmanager) \ + { \ + AnscZeroMemory(component_com_wanmanager, sizeof(COMPONENT_COMMON_WANMANAGER)); \ + component_com_wanmanager->Name = NULL; \ + component_com_wanmanager->Version = 1; \ + component_com_wanmanager->Author = NULL; \ + component_com_wanmanager->Health = COMMON_COMPONENT_HEALTH_Red; \ + component_com_wanmanager->State = COMMON_COMPONENT_STATE_Running; \ + if(g_iTraceLevel >= CCSP_TRACE_LEVEL_EMERGENCY) \ + component_com_wanmanager->LogLevel = (ULONG) g_iTraceLevel; \ + component_com_wanmanager->LogEnable = TRUE; \ + component_com_wanmanager->MemMaxUsage = 0; \ + component_com_wanmanager->MemMinUsage = 0; \ + component_com_wanmanager->MemConsumed = 0; \ + } + + +#define ComponentCommonDmClean(component_com_wanmanager) \ + { \ + if ( component_com_wanmanager->Name ) \ + { \ + AnscFreeMemory(component_com_wanmanager->Name); \ + } \ + \ + if ( component_com_wanmanager->Author ) \ + { \ + AnscFreeMemory(component_com_wanmanager->Author); \ + } \ + } + + +#define ComponentCommonDmFree(component_com_wanmanager) \ + { \ + ComponentCommonDmClean(component_com_wanmanager); \ + AnscFreeMemory(component_com_wanmanager); \ + } + +int cmd_dispatch(int command); + + +ANSC_STATUS ssp_create(); +ANSC_STATUS ssp_engage(); +ANSC_STATUS ssp_cancel(); + + +char* ssp_CcdIfGetComponentName(ANSC_HANDLE hThisObject); +ULONG ssp_CcdIfGetComponentVersion(ANSC_HANDLE hThisObject); +char* ssp_CcdIfGetComponentAuthor(ANSC_HANDLE hThisObject); +ULONG ssp_CcdIfGetComponentHealth(ANSC_HANDLE hThisObject); +ULONG ssp_CcdIfGetComponentState(ANSC_HANDLE hThisObject); + +BOOL ssp_CcdIfGetLoggingEnabled(ANSC_HANDLE hThisObject); +ANSC_STATUS ssp_CcdIfSetLoggingEnabled(ANSC_HANDLE hThisObject, BOOL bEnabled); +ULONG ssp_CcdIfGetLoggingLevel(ANSC_HANDLE hThisObject); +ANSC_STATUS ssp_CcdIfSetLoggingLevel(ANSC_HANDLE hThisObject, ULONG LogLevel); + +ULONG ssp_CcdIfGetMemMaxUsage(ANSC_HANDLE hThisObject); +ULONG ssp_CcdIfGetMemMinUsage(ANSC_HANDLE hThisObject); +ULONG ssp_CcdIfGetMemConsumed(ANSC_HANDLE hThisObject); +ANSC_STATUS ssp_CcdIfApplyChanges(ANSC_HANDLE hThisObject); + + +#endif //_WANMGR_SSP_INTERNAL_H_ diff --git a/source/WanManager/wanmgr_ssp_messagebus_interface.c b/source/WanManager/wanmgr_ssp_messagebus_interface.c new file mode 100644 index 00000000..ee5f618d --- /dev/null +++ b/source/WanManager/wanmgr_ssp_messagebus_interface.c @@ -0,0 +1,212 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2017 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + + +/********************************************************************************* + + description: + + This is the template file of ssp_messagebus_interface.c for XxxxSsp. + You may fill in the functions below if needed. + + * ssp_Mbi_Initialize + * ssp_finalize + * ssp_Mbi_BusCheck + * ssp_Mbi_FreeResources + + ------------------------------------------------------------------------------ + + revision: + + 09/08/2011 initial revision. + +**********************************************************************************/ + +#include "wanmgr_ssp_global.h" + + +ANSC_HANDLE bus_handle = NULL; +extern char g_Subsystem[32]; +extern ANSC_HANDLE g_MessageBusHandle_Irep; +extern char g_SubSysPrefix_Irep[32]; + +#ifdef _ANSC_LINUX +DBusHandlerResult +CcspComp_path_message_func(DBusConnection *conn, DBusMessage *message, void *user_data) +{ + CCSP_MESSAGE_BUS_INFO *bus_info =(CCSP_MESSAGE_BUS_INFO *) user_data; + const char *interface = dbus_message_get_interface(message); + const char *method = dbus_message_get_member(message); + DBusMessage *reply; + + reply = dbus_message_new_method_return (message); + if (reply == NULL) + { + return DBUS_HANDLER_RESULT_HANDLED; + } + + return CcspBaseIf_base_path_message_func + ( + conn, + message, + reply, + interface, + method, + bus_info + ); +} + +ANSC_STATUS +ssp_Mbi_MessageBusEngage(char* component_id, char* config_file, char* path) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + CCSP_Base_Func_CB cb = {0}; + + if ( ! component_id || ! path ) + { + CcspTraceError((" !!! ssp_Mbi_MessageBusEngage: component_id or path is NULL !!!\n")); + } + + /* Connect to message bus */ + returnStatus = + CCSP_Message_Bus_Init + ( component_id, + config_file, + &bus_handle, + Ansc_AllocateMemory_Callback, /* mallocfc, use default */ + Ansc_FreeMemory_Callback /* freefc, use default */ + ); + + if ( returnStatus != ANSC_STATUS_SUCCESS ) + { + CcspTraceError((" !!! SSD Message Bus Init ERROR !!!\n")); + + return returnStatus; + } + + CcspTraceInfo(("INFO: bus_handle: 0x%8x \n", bus_handle)); + g_MessageBusHandle_Irep = bus_handle; + AnscCopyString(g_SubSysPrefix_Irep, g_Subsystem); + + CCSP_Msg_SleepInMilliSeconds(1000); + + /* Base interface implementation that will be used cross components */ + cb.getParameterValues = CcspCcMbi_GetParameterValues; + cb.setParameterValues = CcspCcMbi_SetParameterValues; + cb.setCommit = CcspCcMbi_SetCommit; + cb.setParameterAttributes = CcspCcMbi_SetParameterAttributes; + cb.getParameterAttributes = CcspCcMbi_GetParameterAttributes; + cb.AddTblRow = CcspCcMbi_AddTblRow; + cb.DeleteTblRow = CcspCcMbi_DeleteTblRow; + cb.getParameterNames = CcspCcMbi_GetParameterNames; + cb.currentSessionIDSignal = CcspCcMbi_CurrentSessionIdSignal; + + /* Base interface implementation that will only be used by ssd */ + cb.initialize = ssp_Mbi_Initialize; + cb.finalize = ssp_Mbi_Finalize; + cb.freeResources = ssp_Mbi_FreeResources; + cb.busCheck = ssp_Mbi_Buscheck; + + CcspBaseIf_SetCallback(bus_handle, &cb); + + /* Register service callback functions */ + returnStatus = + CCSP_Message_Bus_Register_Path + ( + bus_handle, + path, + CcspComp_path_message_func, + bus_handle + ); + + if ( returnStatus != CCSP_Message_Bus_OK ) + { + CcspTraceError((" !!! CCSP_Message_Bus_Register_Path ERROR returnStatus: %d\n!!!\n", returnStatus)); + + return returnStatus; + } + + + /* Register event/signal */ + returnStatus = + CcspBaseIf_Register_Event + ( + bus_handle, + 0, + "currentSessionIDSignal" + ); + + if ( returnStatus != CCSP_Message_Bus_OK ) + { + CcspTraceError((" !!! CCSP_Message_Bus_Register_Event: CurrentSessionIDSignal ERROR returnStatus: %d!!!\n", returnStatus)); + + return returnStatus; + } + + return ANSC_STATUS_SUCCESS; + +} + +#endif + +int +ssp_Mbi_Initialize(void* user_data) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + + return ( returnStatus == ANSC_STATUS_SUCCESS ) ? 0 : 1; +} + + +int +ssp_Mbi_Finalize(void* user_data) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + + returnStatus = ssp_cancel(); + + return ( returnStatus == ANSC_STATUS_SUCCESS ) ? 0 : 1; +} + + +int +ssp_Mbi_Buscheck(void* user_data) +{ + return 0; +} + + +int +ssp_Mbi_FreeResources(int priority, void* user_data) +{ + ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; + + if ( priority == COMMON_COMPONENT_FREERESOURCES_PRIORITY_Low ) + { + /* Currently do nothing */ + } + else if ( priority == COMMON_COMPONENT_FREERESOURCES_PRIORITY_High ) + { + returnStatus = ssp_cancel(); + } + + return ( returnStatus == ANSC_STATUS_SUCCESS ) ? 0 : 1; +} + + diff --git a/source/WanManager/wanmgr_ssp_messagebus_interface.h b/source/WanManager/wanmgr_ssp_messagebus_interface.h new file mode 100644 index 00000000..6f9266c4 --- /dev/null +++ b/source/WanManager/wanmgr_ssp_messagebus_interface.h @@ -0,0 +1,45 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2017 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + + +/********************************************************************************* + + description: + + This is the template file of ssp_messagebus_interface.h for XxxxSsp. + You don't need to do anything here. + + ------------------------------------------------------------------------------ + + revision: + + 09/08/2011 initial revision. + +**********************************************************************************/ + +#ifndef _SSP_MESSAGEBUS_INTERFACE_ +#define _SSP_MESSAGEBUS_INTERFACE_ + +ANSC_STATUS ssp_Mbi_MessageBusEngage (char * component_id, char * config_file, char * path); +int ssp_Mbi_Initialize (void * user_data); +int ssp_Mbi_Finalize (void * user_data); +int ssp_Mbi_Buscheck (void * user_data); +int ssp_Mbi_FreeResources (int priority, void * user_data); + +#endif diff --git a/source/WanManager/wanmgr_sysevents.c b/source/WanManager/wanmgr_sysevents.c new file mode 100644 index 00000000..b5fc6f46 --- /dev/null +++ b/source/WanManager/wanmgr_sysevents.c @@ -0,0 +1,763 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2017 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +#include +#include +#include +#include + +#include "wanmgr_sysevents.h" +#include "wanmgr_rdkbus_utils.h" + +int sysevent_fd = -1; +token_t sysevent_token; +static int sysevent_msg_fd = -1; +static token_t sysevent_msg_token; + +#define PAM_COMPONENT_NAME "eRT.com.cisco.spvtg.ccsp.pam" +#define PAM_DBUS_PATH "/com/cisco/spvtg/ccsp/pam" +#define WANMGR_SYSNAME_RCV "wanmanager" +#define WANMGR_SYSNAME_SND "wanmgr" +#define SYS_IP_ADDR "127.0.0.1" +#define BUFLEN_42 42 +#define SYSEVENT_VALUE_READY "ready" +#define SYSEVENT_VALUE_STARTED "started" +#define SYSEVENT_OPEN_MAX_RETRIES 6 +#define BRG_INST_SIZE 5 +#define BUF_SIZE 256 +#define SKY_DHCPV6_OPTIONS "/var/skydhcp6_options.txt" +#define ENTERPRISE_ID 3561 //Broadband Forum. +#define OPTION_16 16 +#define WAN_PHY_ADDRESS "/sys/class/net/erouter0/address" +#define LAN_BRIDGE_NAME "brlan0" + +static int pnm_inited = 0; +static int lan_wan_started = 0; +static int ipv4_connection_up = 0; +static int ipv6_connection_up = 0; +static void check_lan_wan_ready(); +static int CheckV6DefaultRule(); +static void do_toggle_v6_status(); +static void lan_start(); +static void set_vendor_spec_conf(); +static int getVendorClassInfo(char *buffer, int length); +static int set_default_conf_entry(); + +static ANSC_STATUS WanMgr_SyseventInit() +{ + ANSC_STATUS ret = ANSC_STATUS_SUCCESS; + bool send_fd_status = FALSE; + bool recv_fd_status = FALSE; + int try = 0; + + /* Open sysevent descriptor to send messages */ + while(try < SYSEVENT_OPEN_MAX_RETRIES) + { + sysevent_fd = sysevent_open(SYS_IP_ADDR, SE_SERVER_WELL_KNOWN_PORT, SE_VERSION, WANMGR_SYSNAME_SND, &sysevent_token); + if(sysevent_fd >= 0) + { + send_fd_status = TRUE; + break; + } + try++; + usleep(50000); + } + + try = 0; + /* Open sysevent descriptor to receive messages */ + while(try < SYSEVENT_OPEN_MAX_RETRIES) + { + sysevent_msg_fd = sysevent_open(SYS_IP_ADDR, SE_SERVER_WELL_KNOWN_PORT, SE_VERSION, WANMGR_SYSNAME_RCV, &sysevent_msg_token); + if(sysevent_msg_fd >= 0) + { + recv_fd_status = TRUE; + break; + } + try++; + usleep(50000); + } + + if (send_fd_status == FALSE || recv_fd_status == FALSE) + { + ret = ANSC_STATUS_FAILURE; + } + + return ret; +} + +static void WanMgr_SyseventClose() +{ + if (0 <= sysevent_fd) + { + sysevent_close(sysevent_fd, sysevent_token); + } + + if (0 <= sysevent_msg_fd) + { + sysevent_close(sysevent_msg_fd, sysevent_msg_token); + } +} + + +ANSC_STATUS syscfg_set_string(const char* name, const char* value) +{ + ANSC_STATUS ret = ANSC_STATUS_SUCCESS; + if (syscfg_set(NULL, name, value) != 0) + { + CcspTraceError(("syscfg_set failed: %s %s\n", name, value)); + ret = ANSC_STATUS_FAILURE; + } + else + { + if (syscfg_commit() != 0) + { + CcspTraceError(("syscfg_commit failed: %s %s\n", name, value)); + ret = ANSC_STATUS_FAILURE; + } + } + + return ret; +} + +ANSC_STATUS syscfg_set_bool(const char* name, int value) +{ + ANSC_STATUS ret = ANSC_STATUS_SUCCESS; + char buf[10]; + memset(buf,0,sizeof(buf)); + + sprintf(buf, "%d", value); + if (syscfg_set(NULL, name, buf) != 0) + { + CcspTraceError(("syscfg_set failed: %s %d\n", name, value)); + ret = ANSC_STATUS_FAILURE; + } + else + { + if (syscfg_commit() != 0) + CcspTraceError(("syscfg_commit failed: %s %d\n", name, value)); + ret = ANSC_STATUS_FAILURE; + } + + return ret; +} + +ANSC_STATUS wanmgr_sysevents_ipv6Info_init() +{ + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_FIELD_IPV6_DNS_PRIMARY, "", 0); + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_FIELD_IPV6_DNS_SECONDARY, "", 0); + sysevent_set(sysevent_fd, sysevent_token,SYSEVENT_FIELD_IPV6_DOMAIN, "", 0); + syscfg_set_string(SYSCFG_FIELD_IPV6_PREFIX_ADDRESS, ""); + return ANSC_STATUS_SUCCESS; +} + +ANSC_STATUS wanmgr_sysevents_ipv4Info_set(const ipc_dhcpv4_data_t* dhcp4Info, const char *wanIfName) +{ + char name[BUFLEN_64] = {0}; + char value[BUFLEN_64] = {0}; + + snprintf(name, sizeof(name), SYSEVENT_CURRENT_WAN_IFNAME); + sysevent_set(sysevent_fd, sysevent_token,name, dhcp4Info->dhcpcInterface, 0); + + snprintf(name, sizeof(name), SYSEVENT_IPV4_IP_ADDRESS, wanIfName); + sysevent_set(sysevent_fd, sysevent_token,name, dhcp4Info->ip, 0); + + //same as SYSEVENT_IPV4_IP_ADDRESS. But this is required in other components + sysevent_set(sysevent_fd, sysevent_token,SYSEVENT_IPV4_WAN_ADDRESS, dhcp4Info->ip, 0); + + snprintf(name, sizeof(name), SYSEVENT_IPV4_SUBNET, wanIfName); + sysevent_set(sysevent_fd, sysevent_token,name, dhcp4Info->mask, 0); + + //same as SYSEVENT_IPV4_SUBNET. But this is required in other components + sysevent_set(sysevent_fd, sysevent_token,SYSEVENT_IPV4_WAN_SUBNET, dhcp4Info->mask, 0); + + snprintf(name, sizeof(name), SYSEVENT_IPV4_GW_NUMBER, wanIfName); + sysevent_set(sysevent_fd, sysevent_token, name, "1", 0); + + snprintf(name, sizeof(name), SYSEVENT_IPV4_GW_ADDRESS, wanIfName); + sysevent_set(sysevent_fd, sysevent_token,name, dhcp4Info->gateway, 0); + sysevent_set(sysevent_fd, sysevent_token,SYSEVENT_IPV4_DEFAULT_ROUTER, dhcp4Info->gateway, 0); + + snprintf(name, sizeof(name), SYSEVENT_IPV4_DNS_NUMBER, wanIfName); + sysevent_set(sysevent_fd, sysevent_token,name, "2", 0); + + snprintf(name, sizeof(name), SYSEVENT_IPV4_DNS_PRIMARY, wanIfName); + sysevent_set(sysevent_fd, sysevent_token,name, dhcp4Info->dnsServer, 0); + + snprintf(name, sizeof(name), SYSEVENT_IPV4_DNS_SECONDARY, wanIfName); + sysevent_set(sysevent_fd, sysevent_token,name, dhcp4Info->dnsServer1, 0); + + snprintf(name, sizeof(name), SYSEVENT_IPV4_DS_CURRENT_RATE, wanIfName); + snprintf(value, sizeof(value), "%d", dhcp4Info->downstreamCurrRate); + sysevent_set(sysevent_fd, sysevent_token,name, value, 0); + + snprintf(name, sizeof(name), SYSEVENT_IPV4_US_CURRENT_RATE, wanIfName); + snprintf(value, sizeof(value), "%d", dhcp4Info->upstreamCurrRate); + sysevent_set(sysevent_fd, sysevent_token,name, value, 0); + + if (dhcp4Info->isTimeOffsetAssigned) + { + snprintf(value, sizeof(value), "@%d", dhcp4Info->timeOffset); + sysevent_set(sysevent_fd, sysevent_token,SYSEVENT_IPV4_TIME_OFFSET, value, 0); + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_DHCPV4_TIME_OFFSET, SET, 0); + } + else + { + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_DHCPV4_TIME_OFFSET, UNSET, 0); + } + + sysevent_set(sysevent_fd, sysevent_token,SYSEVENT_IPV4_TIME_ZONE, dhcp4Info->timeZone, 0); + + snprintf(name,sizeof(name),SYSEVENT_IPV4_DHCP_SERVER,dhcp4Info->dhcpcInterface); + sysevent_set(sysevent_fd, sysevent_token,name, dhcp4Info->dhcpServerId,0); + + snprintf(name,sizeof(name),SYSEVENT_IPV4_DHCP_STATE ,dhcp4Info->dhcpcInterface); + sysevent_set(sysevent_fd, sysevent_token,name, dhcp4Info->dhcpState,0); + + snprintf(name,sizeof(name), SYSEVENT_IPV4_LEASE_TIME, dhcp4Info->dhcpcInterface); + snprintf(value, sizeof(value), "%u",dhcp4Info->leaseTime); + sysevent_set(sysevent_fd, sysevent_token,name, value, 0); + + return ANSC_STATUS_SUCCESS; +} + +ANSC_STATUS wanmgr_sysevents_ipv4Info_init(const char *wanIfName) +{ + char name[BUFLEN_64] = {0}; + char value[BUFLEN_64] = {0}; + ipc_dhcpv4_data_t ipv4Data; + + memset(&ipv4Data, 0, sizeof(ipc_dhcpv4_data_t)); + strncpy(ipv4Data.ip, "0.0.0.0", strlen("0.0.0.0")); + strncpy(ipv4Data.mask, "0.0.0.0", strlen("0.0.0.0")); + strncpy(ipv4Data.gateway, "0.0.0.0", strlen("0.0.0.0")); + strncpy(ipv4Data.dnsServer, "0.0.0.0", strlen("0.0.0.0")); + strncpy(ipv4Data.dnsServer1, "0.0.0.0", strlen("0.0.0.0")); + sysevent_set(sysevent_fd, sysevent_token,SYSEVENT_CURRENT_WAN_IPADDR, "0.0.0.0", 0); + snprintf(name, sizeof(name), SYSEVENT_IPV4_START_TIME, wanIfName); + sysevent_set(sysevent_fd, sysevent_token,name, "0", 0); + return wanmgr_sysevents_ipv4Info_set(&ipv4Data, wanIfName); +} + + +void wanmgr_sysevents_setWanLedState(const char * LedState) +{ + if (sysevent_fd == -1) return; + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_WAN_LED_STATE, LedState, 0); +} + + +#ifdef FEATURE_MAPT +ANSC_STATUS maptInfo_set(const MaptData_t *maptInfo) +{ + if (NULL == maptInfo) + { + CcspTraceError(("Invalid arguments \n")); + return ANSC_STATUS_FAILURE; + } + + char name[BUFLEN_64] = {0}; + char value[BUFLEN_64] = {0}; + + snprintf(name, sizeof(name), SYSEVENT_MAPT_CONFIG_FLAG); + sysevent_set(sysevent_fd, sysevent_token,name, maptInfo->maptConfigFlag, 0); + + snprintf(name, sizeof(name),SYSEVENT_MAPT_RATIO); + snprintf(value, sizeof(value), "%d", maptInfo->ratio); + sysevent_set(sysevent_fd, sysevent_token,name, value, 0); + + snprintf(name, sizeof(name), SYSEVENT_MAPT_IPADDRESS); + sysevent_set(sysevent_fd, sysevent_token,name, maptInfo->ipAddressString, 0); + + snprintf(name, sizeof(name), SYSEVENT_MAP_BR_IPV6_PREFIX); + sysevent_set(sysevent_fd, sysevent_token,name, maptInfo->brIpv6PrefixString, 0); + + snprintf(name, sizeof(name), SYSEVENT_MAP_RULE_IPADDRESS); + sysevent_set(sysevent_fd, sysevent_token,name, maptInfo->ruleIpAddressString, 0); + + snprintf(name, sizeof(name), SYSEVENT_MAPT_IPV6_ADDRESS); + sysevent_set(sysevent_fd, sysevent_token,name, maptInfo->ipv6AddressString, 0); + + snprintf(name, sizeof(name), SYSEVENT_MAP_RULE_IPV6_ADDRESS); + sysevent_set(sysevent_fd, sysevent_token,name, maptInfo->ruleIpv6AddressString, 0); + + snprintf(name, sizeof(name), SYSEVENT_MAPT_PSID_OFFSET); + snprintf(value, sizeof(value), "%d", maptInfo->psidOffset); + sysevent_set(sysevent_fd, sysevent_token,name, value, 0); + + snprintf(name, sizeof(name), SYSEVENT_MAPT_PSID_VALUE); + snprintf(value, sizeof(value), "%d", maptInfo->psidValue); + sysevent_set(sysevent_fd, sysevent_token,name, value, 0); + + snprintf(name, sizeof(name), SYSEVENT_MAPT_PSID_LENGTH); + snprintf(value, sizeof(value), "%d", maptInfo->psidLen); + sysevent_set(sysevent_fd, sysevent_token,name, value, 0); + + if(maptInfo->maptAssigned) + { + strncpy(value, "MAPT", 4); + } + else if(maptInfo->mapeAssigned) + { + strncpy(value, "MAPE", 4); + } + else + { + strncpy(value, "NON-MAP", 7); + } + sysevent_set(sysevent_fd, sysevent_token,SYSEVENT_MAP_TRANSPORT_MODE, value, 0); + + if(maptInfo->isFMR ==1) + { + strncpy(value, "TRUE", 4); + } + else + { + strncpy(value, "FALSE", 5); + } + sysevent_set(sysevent_fd, sysevent_token,SYSEVENT_MAP_IS_FMR, value, 0); + + snprintf(value, sizeof(value), "%d", maptInfo->eaLen); + sysevent_set(sysevent_fd, sysevent_token,SYSEVENT_MAP_EA_LENGTH, value, 0); + + return ANSC_STATUS_SUCCESS; +} + +ANSC_STATUS maptInfo_reset() +{ + sysevent_set(sysevent_fd, sysevent_token,SYSEVENT_MAPT_CONFIG_FLAG, RESET, 0); + + sysevent_set(sysevent_fd, sysevent_token,SYSEVENT_MAPT_RATIO, "", 0); + + sysevent_set(sysevent_fd, sysevent_token,SYSEVENT_MAPT_IPADDRESS, "", 0); + + sysevent_set(sysevent_fd, sysevent_token,SYSEVENT_MAPT_IPV6_ADDRESS, "", 0); + + sysevent_set(sysevent_fd, sysevent_token,SYSEVENT_MAPT_PSID_OFFSET, "", 0); + + sysevent_set(sysevent_fd, sysevent_token,SYSEVENT_MAPT_PSID_VALUE, "", 0); + + sysevent_set(sysevent_fd, sysevent_token,SYSEVENT_MAPT_PSID_LENGTH, "", 0); + + sysevent_set(sysevent_fd, sysevent_token,SYSEVENT_MAP_TRANSPORT_MODE, "", 0); + + sysevent_set(sysevent_fd, sysevent_token,SYSEVENT_MAP_IS_FMR, "", 0); + + sysevent_set(sysevent_fd, sysevent_token,SYSEVENT_MAP_EA_LENGTH, "", 0); + + return ANSC_STATUS_SUCCESS; +} +#endif // FEATURE_MAPT + +static int set_default_conf_entry() +{ + char command[BUFLEN_64]; + char result[BUFLEN_64]; + FILE *fp; + + syscfg_init(); + memset(command, 0, sizeof(command)); + memset(result, 0, sizeof(result)); + + snprintf(command, sizeof(command), "cat %s", WAN_PHY_ADDRESS); + fp = popen(command, "r"); + fgets(result, sizeof(result), fp); + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_ETH_WAN_MAC, result, 0); + pclose(fp); + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_BRIDGE_MODE, "0", 0); // to boot in router mode + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_TOPOLOGY_MODE, "1", 0); + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_MULTINET_INSTANCES, LAN_BRIDGE_NAME, 0); + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_MULTINET_NAME, LAN_BRIDGE_NAME, 0); + syscfg_set(NULL, SYSEVENT_LAN_PD_INTERFACES, LAN_BRIDGE_NAME); // sets the lan interface for prefix deligation + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_WAN_START, "", 0); + syscfg_set(NULL, SYSCFG_ETH_WAN_ENABLED, "true"); // to handle Factory reset case + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_ETHWAN_INITIALIZED, "0", 0); + syscfg_set(NULL, SYSCFG_NTP_ENABLED, "1"); // Enable NTP in case of ETHWAN + + syscfg_commit(); + + return 0; +} + +static void *WanManagerSyseventHandler(void *args) +{ + CcspTraceInfo(("%s %d \n", __FUNCTION__, __LINE__)); + + //detach thread from caller stack + pthread_detach(pthread_self()); + + async_id_t wanamangr_status_asyncid; + async_id_t lan_ula_address_event_asyncid; + async_id_t lan_ula_enable_asyncid; + async_id_t lan_ipv6_enable_asyncid; + async_id_t wan_status_asyncid; + async_id_t wan_service_status_asyncid; + async_id_t pnm_status_asyncid; + async_id_t lan_status_asyncid; + async_id_t primary_lan_l3net_asyncid; + async_id_t radvd_restart_asyncid; + async_id_t ipv6_down_asyncid; + + sysevent_set_options(sysevent_msg_fd, sysevent_msg_token, SYSEVENT_ULA_ADDRESS, TUPLE_FLAG_EVENT); + sysevent_setnotification(sysevent_msg_fd, sysevent_msg_token, SYSEVENT_ULA_ADDRESS, &lan_ula_address_event_asyncid); + + sysevent_set_options(sysevent_msg_fd, sysevent_msg_token, SYSEVENT_ULA_ENABLE, TUPLE_FLAG_EVENT); + sysevent_setnotification(sysevent_msg_fd, sysevent_msg_token, SYSEVENT_ULA_ENABLE, &lan_ula_enable_asyncid); + + sysevent_set_options(sysevent_msg_fd, sysevent_msg_token, SYSEVENT_IPV6_ENABLE, TUPLE_FLAG_EVENT); + sysevent_setnotification(sysevent_msg_fd, sysevent_msg_token, SYSEVENT_IPV6_ENABLE, &lan_ipv6_enable_asyncid); + + sysevent_set_options(sysevent_msg_fd, sysevent_msg_token, SYSEVENT_WAN_STATUS, TUPLE_FLAG_EVENT); + sysevent_setnotification(sysevent_msg_fd, sysevent_msg_token, SYSEVENT_WAN_STATUS, &wan_status_asyncid); + + sysevent_set_options(sysevent_msg_fd, sysevent_msg_token, SYSEVENT_WAN_SERVICE_STATUS, TUPLE_FLAG_EVENT); + sysevent_setnotification(sysevent_msg_fd, sysevent_msg_token, SYSEVENT_WAN_SERVICE_STATUS, &wan_service_status_asyncid); + + sysevent_set_options(sysevent_msg_fd, sysevent_msg_token, SYSEVENT_PNM_STATUS, TUPLE_FLAG_EVENT); + sysevent_setnotification(sysevent_msg_fd, sysevent_msg_token, SYSEVENT_PNM_STATUS, &pnm_status_asyncid); + + sysevent_set_options(sysevent_msg_fd, sysevent_msg_token, SYSEVENT_LAN_STATUS, TUPLE_FLAG_EVENT); + sysevent_setnotification(sysevent_msg_fd, sysevent_msg_token, SYSEVENT_LAN_STATUS, &lan_status_asyncid); + + sysevent_set_options(sysevent_msg_fd, sysevent_msg_token, SYSEVENT_PRIMARY_LAN_L3NET, TUPLE_FLAG_EVENT); + sysevent_setnotification(sysevent_msg_fd, sysevent_msg_token, SYSEVENT_PRIMARY_LAN_L3NET, &primary_lan_l3net_asyncid); + + sysevent_set_options(sysevent_msg_fd, sysevent_msg_token, SYSEVENT_RADVD_RESTART, TUPLE_FLAG_EVENT); + sysevent_setnotification(sysevent_msg_fd, sysevent_msg_token, SYSEVENT_RADVD_RESTART, &radvd_restart_asyncid); + + sysevent_set_options(sysevent_msg_fd, sysevent_msg_token, SYSEVENT_GLOBAL_IPV6_PREFIX_CLEAR, TUPLE_FLAG_EVENT); + sysevent_setnotification(sysevent_msg_fd, sysevent_msg_token, SYSEVENT_GLOBAL_IPV6_PREFIX_CLEAR, &ipv6_down_asyncid); + for(;;) + { + char name[BUFLEN_42] = {0}; + char val[BUFLEN_42] = {0}; + char buf[BUF_SIZE] = {0}; + int namelen = sizeof(name); + int vallen = sizeof(val); + async_id_t getnotification_asyncid; + int err = 0; + ANSC_STATUS result = 0; + char *datamodel_value = NULL; + char brlan0_inst[BRG_INST_SIZE]; + char* l3net_inst = NULL; + int l2net_inst_up = FALSE; + + err = sysevent_getnotification(sysevent_msg_fd, sysevent_msg_token, name, &namelen, val, &vallen, &getnotification_asyncid); + + if(err) + { + CcspTraceError(("%s %d sysevent_getnotification failed with error: %d \n", __FUNCTION__, __LINE__, err )); + sleep(2); + } + else + { + CcspTraceInfo(("%s %d - received notification event %s:%s\n", __FUNCTION__, __LINE__, name, val )); + if ( strcmp(name, SYSEVENT_ULA_ADDRESS) == 0 ) + { + datamodel_value = (char *) malloc(sizeof(char) * 256); + if(datamodel_value != NULL) + { + memset(datamodel_value, 0, 256); + strncpy(datamodel_value, val, sizeof(val)); + result = WanMgr_RdkBus_SetParamValues( PAM_COMPONENT_NAME, PAM_DBUS_PATH, "Device.DHCPv6.Server.Pool.1.X_RDKCENTRAL-COM_DNSServersEnabled", "true", ccsp_boolean, TRUE ); + if(result == ANSC_STATUS_SUCCESS) + { + result = WanMgr_RdkBus_SetParamValues( PAM_COMPONENT_NAME, PAM_DBUS_PATH, "Device.DHCPv6.Server.Pool.1.X_RDKCENTRAL-COM_DNSServers", datamodel_value, ccsp_string, TRUE ); + if(result != ANSC_STATUS_SUCCESS) { + CcspTraceError(("%s %d - SetDataModelParameter() failed for X_RDKCENTRAL-COM_DNSServers parameter \n", __FUNCTION__, __LINE__)); + } + } + else { + CcspTraceError(("%s %d - SetDataModelParameter() failed for X_RDKCENTRAL-COM_DNSServersEnabled parameter \n", __FUNCTION__, __LINE__)); + } + free(datamodel_value); + } + } + else if ( strcmp(name, SYSEVENT_ULA_ENABLE) == 0 ) + { + datamodel_value = (char *) malloc(sizeof(char) * 256); + if(datamodel_value != NULL) + { + memset(datamodel_value, 0, 256); + strncpy(datamodel_value, val, sizeof(val)); + result = WanMgr_RdkBus_SetParamValues( PAM_COMPONENT_NAME, PAM_DBUS_PATH, "Device.DHCPv6.Server.Pool.1.X_RDKCENTRAL-COM_DNSServersEnabled", datamodel_value, ccsp_boolean, TRUE ); + if(result != ANSC_STATUS_SUCCESS) + { + CcspTraceError(("%s %d - SetDataModelParameter failed on dns_enable request \n", __FUNCTION__, __LINE__)); + } + } + free(datamodel_value); + } + else if ( strcmp(name, SYSEVENT_IPV6_ENABLE) == 0 ) + { + datamodel_value = (char *) malloc(sizeof(char) * 256); + if(datamodel_value != NULL) + { + memset(datamodel_value, 0, 256); + strncpy(datamodel_value, val, sizeof(val)); + result = WanMgr_RdkBus_SetParamValues( PAM_COMPONENT_NAME, PAM_DBUS_PATH, "Device.DHCPv6.Server.Pool.1.Enable", datamodel_value, ccsp_boolean, TRUE ); + if(result != ANSC_STATUS_SUCCESS) + { + CcspTraceError(("%s %d - SetDataModelParameter failed on ipv6_enable request \n", __FUNCTION__, __LINE__ )); + } + free(datamodel_value); + system("sysevent set zebra-restart"); + } + } + else if ((strcmp(name, SYSEVENT_WAN_STATUS) == 0) && (strcmp(val, SYSEVENT_VALUE_STARTED) == 0)) + { + if (!lan_wan_started) + { + check_lan_wan_ready(); + } + system("touch /tmp/phylink_wan_state_up"); + } + else if (strcmp(name, SYSEVENT_WAN_SERVICE_STATUS) == 0) + { + CcspTraceError(("%s %d - received notification event %s:%s\n", __FUNCTION__, __LINE__, name, val )); + if (strcmp(val, SYSEVENT_VALUE_STARTED) == 0) { + do_toggle_v6_status(); + } + } + else if (strcmp(name, SYSEVENT_PNM_STATUS) == 0) + { + if (strcmp(val, STATUS_UP_STRING)==0) + { + pnm_inited = 1; + lan_start(); + system("firewall && execute_dir /etc/utopia/post.d/ restart"); + } + } + else if (strcmp(name, SYSEVENT_PRIMARY_LAN_L3NET) == 0) + { + if (pnm_inited) + { + lan_start(); + } + } + else if (strcmp(name, SYSEVENT_LAN_STATUS) == 0 ) + { + char wanStatus[BUFLEN_16] = {0}; + if (strcmp(val, SYSEVENT_VALUE_STARTED) == 0) + { + sysevent_get(sysevent_fd, sysevent_token, SYSEVENT_PRIMARY_LAN_L3NET, buf, sizeof(buf)); + strncpy(brlan0_inst, buf, BRG_INST_SIZE-1); + sysevent_get(sysevent_fd, sysevent_token, SYSEVENT_L3NET_INSTANCES, buf, sizeof(buf)); + l3net_inst = strtok(buf, " "); + while(l3net_inst != NULL) + { + if(!(strcmp(l3net_inst, brlan0_inst)==0)) + { + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_IPV4_UP, l3net_inst, 0); + l2net_inst_up = TRUE; + } + l3net_inst = strtok(NULL, " "); + } + if(l2net_inst_up == FALSE) + { + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_IPV4_UP, brlan0_inst, 0); + } + sysevent_get(sysevent_fd, sysevent_token, SYSEVENT_WAN_SERVICE_STATUS, wanStatus, sizeof(wanStatus)); + if(strcmp(wanStatus, SYSEVENT_VALUE_STARTED) == 0) + { + do_toggle_v6_status(); + } + memset(buf, '\0', sizeof(buf)); + sysevent_get(sysevent_fd, sysevent_token, SYSEVENT_ULA_ADDRESS, buf, sizeof(buf)); + if(buf[0] != '\0') { + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_LAN_ULA_ADDRESS, buf, 0); + } + set_vendor_spec_conf(); + system("gw_lan_refresh &"); +#ifdef FEATURE_MAPT + memset(buf, '\0', sizeof(buf)); + sysevent_get(sysevent_fd, sysevent_token, SYSEVENT_MAP_TRANSPORT_MODE, buf, sizeof(buf)); + if( !strcmp(buf, "MAPT") || !strcmp(buf, "MAPE") ) { + set_mapt_rule(); + } +#endif + } + } + else if (strcmp(name, SYSEVENT_RADVD_RESTART) == 0) + { + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_FIELD_SERVICE_ROUTED_STATUS, "", 0); + system("service_routed radv-restart"); + } + else if (strcmp(name, SYSEVENT_GLOBAL_IPV6_PREFIX_CLEAR) == 0) + { + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_IPV6_CONNECTION_STATE, STATUS_DOWN_STRING, 0); + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_FIREWALL_RESTART, NULL, 0); + } + else + { + CcspTraceError(("%s %d undefined event %s:%s \n", __FUNCTION__, __LINE__, name, val)); + } + } + } + + CcspTraceInfo(("%s %d - WanManagerSyseventHandler Exit \n", __FUNCTION__, __LINE__)); + return 0; +} + +static void lan_start() +{ + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_LAN_START, "", 0); + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_DHCP_SERVER_RESYNC, "", 0); + return; +} +static void check_lan_wan_ready() +{ + char lan_st[BUFLEN_16]; + char wan_st[BUFLEN_16]; + memset(lan_st,0,sizeof(lan_st)); + memset(wan_st,0,sizeof(wan_st)); + sysevent_get(sysevent_fd, sysevent_token, SYSEVENT_LAN_STATUS, lan_st, sizeof(lan_st)); + sysevent_get(sysevent_fd, sysevent_token, SYSEVENT_WAN_STATUS, wan_st, sizeof(wan_st)); + + CcspTraceInfo(("****************************************************\n")); + CcspTraceInfo((" Lan Status = %s Wan Status = %s\n", lan_st, wan_st)); + CcspTraceInfo(("****************************************************\n")); + if (!strcmp(lan_st, SYSEVENT_VALUE_STARTED) && !strcmp(wan_st, SYSEVENT_VALUE_STARTED)) + { + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_START_MISC, SYSEVENT_VALUE_READY, 0); + lan_wan_started = 1; + } + return; +} +static int CheckV6DefaultRule() +{ + int ret = FALSE; + FILE *fp = NULL; + char buf[256] = {0}; + char output[256] = {0}; + + snprintf(buf, sizeof(buf), " ip -6 ro | grep default | grep via | grep erouter0"); + if(!(fp = popen(buf, "r"))) + { + return -1; + } + while(fgets(output, sizeof(output), fp)!=NULL) + { + ret = TRUE; // Default rout entry exist + } + + pclose(fp); + return ret; +} + +static void do_toggle_v6_status() +{ + char cmdLine[BUFLEN_128] = {0}; + bool isV6DefaultRoutePresent = FALSE; + isV6DefaultRoutePresent = CheckV6DefaultRule(); + if ( isV6DefaultRoutePresent != TRUE) + { + snprintf(cmdLine, sizeof(cmdLine), "echo 1 > /proc/sys/net/ipv6/conf/erouter0/disable_ipv6"); + system(cmdLine); + snprintf(cmdLine, sizeof(cmdLine), "echo 0 > /proc/sys/net/ipv6/conf/erouter0/disable_ipv6"); + system(cmdLine); + } + return; +} + +static void set_vendor_spec_conf() +{ + char vendor_class[BUF_SIZE] = {0}; + if(getVendorClassInfo(vendor_class, BUF_SIZE) == 0) + { + char vendor_spec_info[BUFLEN_512] = {0}; + sprintf(vendor_spec_info, "%d-%d-\"%s\"", ENTERPRISE_ID, OPTION_16, vendor_class); + CcspTraceInfo(("vendor_spec information = %s \n", vendor_spec_info)); + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_VENDOR_SPEC, vendor_spec_info, 0); + } + else + { + CcspTraceError(("getVendorClassInfo failed")); + } +} + +static int getVendorClassInfo(char *buffer, int length) +{ + FILE * fp; + char * line = NULL; + size_t len = 0; + ssize_t characters; + fp = fopen(SKY_DHCPV6_OPTIONS, "r"); + if (fp == NULL) { + //AnscTraceFlow(("%s file not found", SKY_DHCPV6_OPTIONS)); + return -1; + } + if ((characters = getline(&line, &len, fp)) != -1) { + if ((characters = getline(&line, &len, fp)) != -1) { + if (line != NULL) { + if (line[characters - 1] == '\n') + line[characters - 1] = '\0'; + strncpy(buffer, line, length); + free(line); + } + } + } + fclose(fp); + return 0; +} + + +ANSC_STATUS WanMgr_SysEvents_Init(void) +{ + ANSC_STATUS retStatus = ANSC_STATUS_SUCCESS; + pthread_t sysevent_tid; + + // Initialise syscfg + if (syscfg_init() < 0) + { + CcspTraceError(("failed to initialise syscfg")); + return ANSC_STATUS_FAILURE; + } + + // Initialize sysevent daemon + retStatus = WanMgr_SyseventInit(); + if (retStatus != ANSC_STATUS_SUCCESS) + { + WanMgr_SyseventClose(); + CcspTraceError(("%s %d - WanMgr_SyseventInit failed \n", __FUNCTION__, __LINE__)); + return ANSC_STATUS_FAILURE; + } + + set_default_conf_entry(); + //Init msg status handler + if(pthread_create(&sysevent_tid, NULL, WanManagerSyseventHandler, NULL) == 0) { + CcspTraceError(("%s %d - DmlWanMsgHandler -- pthread_create successfully \n", __FUNCTION__, __LINE__)); + } + else { + CcspTraceError(("%s %d - DmlWanMsgHandler -- pthread_create failed \n", __FUNCTION__, __LINE__)); + } + + //Initialize syscfg value of ipv6 address to release previous value + syscfg_set_string(SYSCFG_FIELD_IPV6_PREFIX_ADDRESS, ""); + + return retStatus; +} + +ANSC_STATUS WanMgr_SysEvents_Finalise(void) +{ + ANSC_STATUS retStatus = ANSC_STATUS_SUCCESS; + + WanMgr_SyseventClose(); + + return retStatus; +} diff --git a/source/WanManager/wanmgr_sysevents.h b/source/WanManager/wanmgr_sysevents.h new file mode 100644 index 00000000..c4bbc742 --- /dev/null +++ b/source/WanManager/wanmgr_sysevents.h @@ -0,0 +1,205 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2015 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + + +#ifndef _WANMGR_SYSEVENTS_H_ +#define _WANMGR_SYSEVENTS_H_ + +#include "ansc_platform.h" +#include "wanmgr_dml.h" + +/********************************************************************** + STRUCTURE AND CONSTANT DEFINITIONS +**********************************************************************/ +// /* sysevent/syscfg configurations used/managed by wanmanager. + +//Led sysevent +#define SYSEVENT_WAN_LED_STATE "wan_led_state" + +#define LED_OFF_STR "Off" +#define LED_FLASHING_AMBER_STR "Flashing Amber" +#define LED_FLASHING_GREEN_STR "Flashing Green" +#define LED_SOLID_AMBER_STR "Solid Amber" +#define LED_SOLID_GREEN_STR "Solid Green" + +// * The following defines are used for sysevent retrieval. */ +#define SYSEVENT_IPV4_CONNECTION_STATE "ipv4_connection_state" +#define SYSEVENT_CURRENT_IPV4_LINK_STATE "current_ipv4_link_state" +#define SYSEVENT_IPV6_CONNECTION_STATE "ipv6_connection_state" +#define SYSEVENT_CURRENT_WAN_STATE "current_wan_state" +#define SYSEVENT_WAN_START_TIME "wan_start_time" +#define SYSEVENT_IPV4_IP_ADDRESS "ipv4_%s_ipaddr" +#define SYSEVENT_IPV4_WAN_ADDRESS "ipv4_wan_ipaddr" +#define SYSEVENT_IPV4_SUBNET "ipv4_%s_subnet" +#define SYSEVENT_IPV4_WAN_SUBNET "ipv4_wan_subnet" +#define SYSEVENT_IPV4_DNS_NUMBER "ipv4_%s_dns_number" +#define SYSEVENT_IPV4_DNS_PRIMARY "ipv4_%s_dns_0" +#define SYSEVENT_IPV4_DNS_SECONDARY "ipv4_%s_dns_1" +#define SYSEVENT_IPV4_GW_NUMBER "ipv4_%s_gw_number" +#define SYSEVENT_IPV4_GW_ADDRESS "ipv4_%s_gw_0" +#define SYSEVENT_VENDOR_CLASS "vendor_class" +#define SYSEVENT_IPV4_DEFAULT_ROUTER "default_router" +#define SYSEVENT_IPV4_TIME_OFFSET "ipv4-timeoffset" +#define SYSEVENT_IPV4_TIME_ZONE "ipv4_timezone" +#define SYSEVENT_DHCPV4_TIME_OFFSET "dhcpv4_time_offset" +#define SYSEVENT_IPV4_US_CURRENT_RATE "ipv4_%s_us_current_rate_0" +#define SYSEVENT_IPV4_DS_CURRENT_RATE "ipv4_%s_ds_current_rate_0" +#define SYSEVENT_FIELD_SERVICE_ROUTED_STATUS "routed-status" + +/*dhcp server restart*/ +#define SYSEVENT_DHCP_SERVER_RESTART "dhcp_server-restart" + +#define SYSCFG_FIELD_IPV6_ADDRESS "wan_ipv6addr" +#define SYSCFG_FIELD_IPV6_PREFIX "ipv6_prefix" +#define SYSCFG_FIELD_IPV6_PREFIX_ADDRESS "ipv6_prefix_address" +#define SYSCFG_FIELD_IPV6_GW_ADDRESS "wan_ipv6_default_gateway" +#define SYSCFG_FIELD_PREVIOUS_IPV6_PREFIX "previousipv6_prefix" +#define SYSEVENT_FIELD_IPV6_PREFIX "ipv6_prefix" +#define SYSEVENT_FIELD_PREVIOUS_IPV6_PREFIX "previous_ipv6_prefix" +#define SYSEVENT_FIELD_LAN_IPV6_START "lan_ipv6-start" +#define SYSEVENT_FIELD_IPV6_DNS_PRIMARY "ipv6_dns_0" +#define SYSEVENT_FIELD_IPV6_DNS_SECONDARY "ipv6_dns_1" +#define SYSEVENT_FIELD_IPV6_DOMAIN "ipv6_domain" +#define SYSEVENT_FIELD_IPV6_PREFIXVLTIME "ipv6_prefix_vldtime" +#define SYSEVENT_FIELD_IPV6_PREFIXPLTIME "ipv6_prefix_prdtime" +#define SYSEVENT_FIELD_PREVIOUS_IPV6_PREFIXVLTIME "previous_ipv6_prefix_vldtime" +#define SYSEVENT_FIELD_PREVIOUS_IPV6_PREFIXPLTIME "previous_ipv6_prefix_prdtime" +#define SYSEVENT_RADVD_RESTART "radvd_restart" +#define SYSEVENT_GLOBAL_IPV6_PREFIX_SET "lan_prefix_set" +#define SYSEVENT_ULA_ADDRESS "ula_address" +#define SYSEVENT_ULA_ENABLE "lan_ula_enable" +#define SYSEVENT_IPV6_ENABLE "lan_ipv6_enable" + +#define SYSEVENT_FIELD_TR_BRLAN0_DHCPV6_SERVER_ADDRESS "tr_brlan0_dhcpv6_server_v6addr" +#define SYSEVENT_FIELD_TR_EROUTER_DHCPV6_CLIENT_PREFIX "tr_erouter0_dhcpv6_client_v6pref" + +/*WAN specific sysevent fieldnames*/ +#define SYSEVENT_CURRENT_WAN_IFNAME "current_wan_ifname" +#define SYSEVENT_WAN_STATUS "wan-status" +#define SYSEVENT_LAN_STATUS "lan-status" +#define SYSEVENT_CURRENT_WAN_IPADDR "current_wan_ipaddr" +#define SYSEVENT_CURRENT_WAN_SUBNET "current_wan_subnet" +#define SYSEVENT_WAN_SERVICE_STATUS "wan_service-status" +#define SYSEVENT_PNM_STATUS "pnm-status" +#define SYSEVENT_LAN_START "lan-start" +#define SYSEVENT_DHCP_SERVER_RESYNC "dhcp_server-resync" +#define SYSEVENT_START_MISC "start-misc" +#define SYSEVENT_PRIMARY_LAN_L3NET "primary_lan_l3net" +#define SYSEVENT_L3NET_INSTANCES "l3net_instances" +#define SYSEVENT_IPV4_UP "ipv4-up" +#define SYSEVENT_LAN_ULA_ADDRESS "lan_ula_address" +#define SYSEVENT_VENDOR_SPEC "vendor_spec" +#define SYSEVENT_PRIMARY_LAN_L3NET "primary_lan_l3net" +#define SYSEVENT_IPV6_PREFIX "ipv6_prefix" +#define SYSEVENT_RADVD_RESTART "radvd_restart" +#define SYSEVENT_GLOBAL_IPV6_PREFIX_CLEAR "lan_prefix_clear" +#define SYSEVENT_ETHWAN_INITIALIZED "ethwan-initialized" +#define SYSEVENT_ETH_WAN_MAC "eth_wan_mac" +#define SYSEVENT_BRIDGE_MODE "bridge_mode" +#define SYSEVENT_WAN_START "wan-start" +#define SYSCFG_ETH_WAN_ENABLED "eth_wan_enabled" +#define SYSCFG_NTP_ENABLED "ntp_enabled" +#define SYSEVENT_LAN_PD_INTERFACES "lan_pd_interfaces" +#define SYSEVENT_MULTINET_NAME "multinet_1-name" +#define SYSEVENT_MULTINET_INSTANCES "multinet-instances" +#define SYSEVENT_TOPOLOGY_MODE "erouter_topology-mode" + +//firewall restart +#define SYSEVENT_FIREWALL_RESTART "firewall-restart" +#define SYSEVENT_FIREWALL_STATUS "firewall-status" + +#define SYSEVENT_IPV4_LEASE_TIME "ipv4_%s_lease_time" +#define SYSEVENT_IPV4_DHCP_SERVER "ipv4_%s_dhcp_server" +#define SYSEVENT_IPV4_DHCP_STATE "ipv4_%s_dhcp_state" +#define SYSEVENT_IPV4_START_TIME "ipv4_%s_start_time" + + +#define WAN_STATUS_STARTED "started" +#define WAN_STATUS_STOPPED "stopped" +#define FIREWALL_STATUS_STARTED "started" +#define STATUS_UP_STRING "up" +#define STATUS_DOWN_STRING "down" +#define SET "set" +#define UNSET "unset" +#define RESET "reset" + +/********************************************************************** + FUNCTION PROTOTYPES +**********************************************************************/ +ANSC_STATUS WanMgr_SysEvents_Init(void); +ANSC_STATUS WanMgr_SysEvents_Finalise(void); + +/* + * @brief Utility function used to set string values to syscfg. + * @param[in] const char* name - Indicates string name represent the value + * @param[in] const char* value- Indicates the value to pass to the curresponding mem + * @return Returns ANSC_STATUS. +*/ +ANSC_STATUS syscfg_set_string(const char* name, const char* value); + +/* + * @brief Utility function used to set bool values to syscfg. + * @param[in] const char* name - Indicates string name represent the value + * @param[in] int value- Indicates the value to pass to the curresponding mem + * @return Returns ANSC_STATUS. +*/ +ANSC_STATUS syscfg_set_bool(const char* name, int value); + +/* + * @brief Utility function used to init all IPv6 values in sysevent + * @param[in] None + * @return Returns ANSC_STATUS. +*/ +ANSC_STATUS wanmgr_sysevents_ipv6Info_init(); + +/* + * @brief Utility function used to init all IPv4 values in sysevent + * @param[in] + * @return Returns ANSC_STATUS. +*/ +ANSC_STATUS wanmgr_sysevents_ipv4Info_init(const char *wanIfName); + +/* + * @brief Utility function used to store all dhcpv4_data_t values in sysevent + * @param[in] dhcpv4_data_t *dhcp4Info + * @return Returns ANSC_STATUS. +*/ +ANSC_STATUS wanmgr_sysevents_ipv4Info_set(const ipc_dhcpv4_data_t* dhcp4Info, const char *wanIfName); + + +/* + * @brief Utility function used to set led state. + * @param[in] const char* LedState - Indicates the led state value + * @return Returns NONE. +*/ +void wanmgr_sysevents_setWanLedState(const char * LedState); + + + +//#ifdef FEATURE_MAPT +///* +// * @brief Utility function used to store MAPT specific values in sysevent/ +// * @param[in] MaptData_t *maptInfo +// * @return Returns ANSC_STATUS_SUCCESS if data properly update in sysevent. +//*/ +//ANSC_STATUS maptInfo_set(const MaptData_t *maptInfo); +//ANSC_STATUS maptInfo_reset(); +//#endif // FEATURE_MAPT + +#endif //_WANMGR_SYSEVENTS_H_ diff --git a/source/WanManager/wanmgr_utils.c b/source/WanManager/wanmgr_utils.c new file mode 100644 index 00000000..6ed767d6 --- /dev/null +++ b/source/WanManager/wanmgr_utils.c @@ -0,0 +1,848 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2015 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + + +/* ---- Include Files ---------------------------------------- */ + +#include +#include +#include /* for waitpid */ +#include "wanmgr_utils.h" +#include "ipc_msg.h" + +/* amount of time to sleep between collect process attempt if timeout was specified. */ +#define COLLECT_WAIT_INTERVAL_MS 40 +#define APP_TERMINATE_TIMEOUT (5 * MSECS_IN_SEC) + +static void freeArgs(char **argv); +static int parseArgs(const char *cmd, const char *args, char ***argv); +static int strtol64(const char *str, char **endptr, int32_t base, int64_t *val); + +static void freeArgs(char **argv) +{ + uint32_t i=0; + while (argv[i] != NULL) + { + if ((argv[i]) != NULL) + { + free((argv[i])); + (argv[i]) = NULL; + } + i++; + } + + if (argv != NULL) + { + free(argv); + argv = NULL; + } +} + +static int parseArgs(const char *cmd, const char *args, char ***argv) +{ + int numArgs=3, i, len, argIndex=0; + bool inSpace=TRUE; + const char *cmdStr; + char **array; + + len = (args == NULL) ? 0 : strlen(args); + + for (i=0; i < len; i++) + { + if ((args[i] == ' ') && (!inSpace)) + { + numArgs++; + inSpace = TRUE; + } + else + { + inSpace = FALSE; + } + } + + array = (char **) malloc ((numArgs) * sizeof(char *)); + if (array == NULL) + { + return -1; + } + + /* locate the command name, last part of string */ + cmdStr = strrchr(cmd, '/'); + if (cmdStr == NULL) + { + cmdStr = cmd; + } + else + { + cmdStr++; + } + + array[argIndex] = calloc (1, strlen(cmdStr) + 1); + + if (array[argIndex] == NULL) + { + CcspTraceError(("memory allocation of %d failed", strlen(cmdStr) + 1)); + freeArgs(array); + return -1; + } + else + { + strcpy(array[argIndex], cmdStr); + argIndex++; + } + + inSpace = TRUE; + for (i=0; i < len; i++) + { + if ((args[i] == ' ') && (!inSpace)) + { + numArgs++; + inSpace = TRUE; + } + else if ((args[i] != ' ') && (inSpace)) + { + int startIndex, endIndex; + + startIndex = i; + endIndex = i; + while ((endIndex < len) && (args[endIndex] != ' ')) + { + endIndex++; + } + + array[argIndex] = calloc(1,endIndex - startIndex + 1); + if (array[argIndex] == NULL) + { + CcspTraceError(("memory allocation of %d failed", endIndex - startIndex + 1)); + freeArgs(array); + return -1; + } + + memcpy(array[argIndex], &args[startIndex], endIndex - startIndex ); + + argIndex++; + + inSpace = FALSE; + } + } + array[argIndex] = NULL; + (*argv) = array; + + return 0; +} + +static int strtol64(const char *str, char **endptr, int32_t base, int64_t *val) +{ + int ret=RETURN_OK; + char *localEndPtr=NULL; + + errno = 0; /* set to 0 so we can detect ERANGE */ + + *val = strtoll(str, &localEndPtr, base); + + if ((errno != 0) || (*localEndPtr != '\0')) + { + *val = 0; + ret = RETURN_ERROR; + } + + if (endptr != NULL) + { + *endptr = localEndPtr; + } + + return ret; +} + +int util_spawnProcess(const char *execName, const char *args, int * processId) +{ + int32_t pid; + char **argv = NULL; + int ret = RETURN_OK; + + if ((ret = parseArgs(execName, args, &argv)) != RETURN_OK) + { + CcspTraceError(("Failed to parse arguments %d\n",ret)); + return ret; + } + + pid = fork(); + if (pid == 0) + { + int32_t devNullFd=-1, fd; + + /* + * This is the child. + */ + + devNullFd = open("/dev/null", O_RDWR); + if (devNullFd == -1) + { + CcspTraceError(("open of /dev/null failed")); + exit(-1); + } + + close(0); + fd = devNullFd; + dup2(fd, 0); + + close(1); + fd = devNullFd; + dup2(fd, 1); + + close(2); + fd = devNullFd; + dup2(fd, 2); + + if (devNullFd != -1) + { + close(devNullFd); + } + + signal(SIGHUP, SIG_DFL); + signal(SIGINT, SIG_DFL); + signal(SIGQUIT, SIG_DFL); + signal(SIGILL, SIG_DFL); + signal(SIGTRAP, SIG_DFL); + signal(SIGABRT, SIG_DFL); /* same as SIGIOT */ + signal(SIGQUIT, SIG_DFL); + signal(SIGILL, SIG_DFL); + signal(SIGTRAP, SIG_DFL); + signal(SIGABRT, SIG_DFL); /* same as SIGIOT */ + signal(SIGFPE, SIG_DFL); + signal(SIGBUS, SIG_DFL); + signal(SIGSEGV, SIG_DFL); + signal(SIGSYS, SIG_DFL); + signal(SIGPIPE, SIG_DFL); + signal(SIGALRM, SIG_DFL); + signal(SIGTERM, SIG_DFL); + signal(SIGUSR1, SIG_DFL); + signal(SIGUSR2, SIG_DFL); + signal(SIGCHLD, SIG_DFL); /* same as SIGCLD */ + signal(SIGPWR, SIG_DFL); + signal(SIGWINCH, SIG_DFL); + signal(SIGURG, SIG_DFL); + signal(SIGIO, SIG_DFL); /* same as SIGPOLL */ + signal(SIGSTOP, SIG_DFL); + signal(SIGTSTP, SIG_DFL); + signal(SIGCONT, SIG_DFL); + signal(SIGTTIN, SIG_DFL); + signal(SIGTTOU, SIG_DFL); + signal(SIGVTALRM, SIG_DFL); + signal(SIGPROF, SIG_DFL); + signal(SIGXCPU, SIG_DFL); + signal(SIGXFSZ, SIG_DFL); + + execv(execName, argv); + /* We should not reach this line. If we do, exec has failed. */ + exit(-1); + } + + freeArgs(argv); + + *processId = pid; + + return ret; +} + +int util_signalProcess(int32_t pid, int32_t sig) +{ + int32_t rc; + + if (pid <= 0) + { + CcspTraceError(("bad pid %d", pid)); + return RETURN_ERROR; + } + + if ((rc = kill(pid, sig)) < 0) + { + CcspTraceError(("invalid signal(%d) or pid(%d)", sig, pid)); + return RETURN_ERROR; + } + + return RETURN_OK; +} + +int util_getNameByPid(int pid, char *nameBuf, int nameBufLen) +{ + FILE *fp; + char processName[BUFLEN_256]; + char filename[BUFLEN_256]; + int rval=-1; + + if (nameBuf == NULL || nameBufLen <= 0) + { + CcspTraceError(("invalid args, nameBuf=%p nameBufLen=%d", nameBuf, nameBufLen)); + return rval; + } + + snprintf(filename, sizeof(filename), "/proc/%d/stat", pid); + if ((fp = fopen(filename, "r")) == NULL) + { + CcspTraceError(("could not open %s", filename)); + } + else + { + int rc, p; + memset(nameBuf, 0, nameBufLen); + memset(processName, 0, sizeof(processName)); + rc = fscanf(fp, "%d (%s", &p, processName); + fclose(fp); + + if (rc >= 2) + { + int c=0; + while (c < nameBufLen-1 && + processName[c] != 0 && processName[c] != ')') + { + nameBuf[c] = processName[c]; + c++; + } + rval = 0; + } + else + { + CcspTraceError(("fscanf of %s failed", filename)); + } + } + + return rval; +} + +int util_getPidByName(const char *name) +{ + DIR *dir; + FILE *fp; + struct dirent *dent; + BOOL found=FALSE; + int pid, rc, p, i; + int rval = 0; + char processName[BUFLEN_256]; + char filename[BUFLEN_256]; + + if (NULL == (dir = opendir("/proc"))) + { + CcspTraceError(("could not open /proc")); + return rval; + } + + while (!found && (dent = readdir(dir)) != NULL) + { + if ((dent->d_type == DT_DIR) && + (RETURN_OK == strtol64(dent->d_name, NULL, 10, (int64_t*)&pid))) + { + snprintf(filename, sizeof(filename), "/proc/%d/stat", pid); + if ((fp = fopen(filename, "r")) == NULL) + { + CcspTraceError(("could not open %s", filename)); + } + else + { + memset(processName, 0, sizeof(processName)); + rc = fscanf(fp, "%d (%s", &p, processName); + fclose(fp); + + if (rc >= 2) + { + i = strlen(processName); + if (i > 0) + { + if (processName[i-1] == ')') + processName[i-1] = 0; + } + } + + if (!strcmp(processName, name)) + { + rval = pid; + found = TRUE; + } + } + } + } + + closedir(dir); + + return rval; +} + +int util_collectProcess(int pid, int timeout) +{ + int32_t rc, status, waitOption=0; + int32_t requestedPid=-1; + uint32_t timeoutRemaining=0; + uint32_t sleepTime; + int ret=RETURN_ERROR; + + requestedPid = pid; + timeoutRemaining = timeout; + + if(timeoutRemaining > 0) + waitOption = WNOHANG; + + timeoutRemaining = (timeoutRemaining <= 1) ? + (timeoutRemaining + 1) : timeoutRemaining; + while (timeoutRemaining > 0) + { + rc = waitpid(requestedPid, &status, waitOption); + if (rc == 0) + { + if (timeoutRemaining > 1) + { + sleepTime = (timeoutRemaining > COLLECT_WAIT_INTERVAL_MS) ? + COLLECT_WAIT_INTERVAL_MS : timeoutRemaining - 1; + usleep(sleepTime * USECS_IN_MSEC); + timeoutRemaining -= sleepTime; + } + else + { + timeoutRemaining = 0; + } + } + else if (rc > 0) + { + pid = rc; + timeoutRemaining = 0; + ret = RETURN_OK; + } + else + { + if (errno == ECHILD) + { + CcspTraceInfo(("Could not collect child pid %d, possibly stolen by SIGCHLD handler?", requestedPid)); + ret = RETURN_ERROR; + } + else + { + CcspTraceError(("bad pid %d, errno=%d", requestedPid, errno)); + ret = RETURN_ERROR; + } + + timeoutRemaining = 0; + } + } + + return ret; +} + +int util_runCommandInShell(char *command) +{ + int pid; + + CcspTraceInfo(("executing %s\n", command)); + pid = fork(); + if (pid == -1) + { + CcspTraceError(("fork failed!")); + return -1; + } + + if (pid == 0) + { + /* this is the child */ + int i; + char *argv[4]; + + /* close all of the child's other fd's */ + for (i=3; i <= 50; i++) + { + close(i); + } + + argv[0] = "sh"; + argv[1] = "-c"; + argv[2] = command; + argv[3] = 0; + execv("/bin/sh", argv); + CcspTraceError(("Should not have reached here!")); + exit(127); + } + + /* parent returns the pid */ + return pid; +} + +int util_runCommandInShellBlocking(char *command) +{ + int processId; + int timeout = 0; + if ( command == 0 ) + return 1; + + if((processId = util_runCommandInShell(command) ) < 0) + { + return 1; + } + if(util_collectProcess(processId, timeout) != 0) + { + CcspTraceError(("Process collection failed\n")); + return -1; + } + return 0; +} + +bool util_isFilePresent(char *filename) +{ + struct stat statbuf; + int32_t rc; + + rc = stat(filename, &statbuf); + + if (rc == 0) + { + return TRUE; + } + else + { + return FALSE; + } +} + + +static int GetRunTimeRootDir(char *pathBuf, uint32_t pathBufLen) +{ + + uint32_t rc; + + rc = snprintf(pathBuf, pathBufLen, "/"); + if (rc >= pathBufLen) + { + AnscTraceError((" %s - %d : pathBufLen %d is too small for buf %s \n", __FUNCTION__,__LINE__, pathBufLen, pathBuf)); + return RETURN_ERROR; + } + + return RETURN_OK; +} + +int GetPathToApp(const char *name, char *buf, uint32_t len) +{ + char envPathBuf[BUFLEN_1024] = {0}; + char rootDirBuf[MAX_FULLPATH_LENGTH] = {0}; + uint32_t i = 0; + uint32_t envPathLen; + int32_t rc; + char *start; + int ret; + + ret = GetRunTimeRootDir(rootDirBuf, sizeof(rootDirBuf)); + if (ret != RETURN_OK) + { + CcspTraceError(("%s %d : GetRunTimeRootDir returns error ret=%d \n", __FUNCTION__,__LINE__, ret)); + return ret; + } + + rc = snprintf(envPathBuf, sizeof(envPathBuf), "%s", getenv("PATH")); + if (rc >= (int32_t)sizeof(envPathBuf)) + { + CcspTraceError(("envPathBuf (size=%d) is too small to hold PATH env %s \n", + sizeof(envPathBuf), getenv("PATH"))); + return RETURN_ERROR; + } + + envPathLen = strlen(envPathBuf); + start = envPathBuf; + + while (i <= envPathLen) + { + if (envPathBuf[i] == ':' || envPathBuf[i] == '\0') + { + envPathBuf[i] = 0; + rc = snprintf(buf, len, "%s%s/%s", rootDirBuf, start, name); + if (rc >= (int32_t)len) + { + CcspTraceError(("MAX_FULLPATH_LENGTH (%d) exceeded on path %s \n", + MAX_FULLPATH_LENGTH, buf)); + return RETURN_ERROR; + } + + if (util_isFilePresent(buf)) + { + return RETURN_OK; + } + i++; + start = &(envPathBuf[i]); + } + else + { + i++; + } + } + + CcspTraceInfo(("not found==>%s \n", name)); + return RETURN_ERROR; +} + +int WanManager_DoSystemActionWithStatus(const char *from, char *cmd) +{ + CcspTraceInfo(("%s -- %s \n", from, cmd)); + return util_runCommandInShellBlocking(cmd); +} + +void WanManager_DoSystemAction(const char *from, char *cmd) +{ + WanManager_DoSystemActionWithStatus(from, cmd); +} + + +BOOL WanManager_IsApplicationRunning(const char *appName) +{ + BOOL isAppRuning = TRUE; + + if (util_getPidByName(appName) <= 0) + isAppRuning = FALSE; + + return isAppRuning; +} + +static int LaunchApp(const char *appName, const char *cmdLineArgs) +{ + char exeBuf[MAX_FULLPATH_LENGTH] = {0}; + int ret = RETURN_OK; + int pid; + + if (ANSC_STATUS_SUCCESS != GetPathToApp(appName, exeBuf, sizeof(exeBuf) - 1)) + { + CcspTraceError(("Could not find requested app %s, not launched! \n", + appName)); + return -1; + } + + CcspTraceInfo(("spawning %s args %s", appName, cmdLineArgs)); + ret = util_spawnProcess(&exeBuf, cmdLineArgs, &pid); + if (ret != RETURN_OK) + { + CcspTraceError(("could not spawn child %s args %s \n", exeBuf, cmdLineArgs)); + } + else + { + CcspTraceError(("%s launched, pid %d", appName, pid)); + } + return pid; +} + +void CollectApp(int pid) +{ + int ret; + int timeout = APP_TERMINATE_TIMEOUT; + + if ((ret = util_collectProcess(pid, timeout)) != RETURN_OK) + { + CcspTraceError(("Could not collect pid=%d timeout=%dms, ret=%d. Kill it with SIGKILL. \n", pid, timeout, ret)); + /* + * Send SIGKILL and collect the process, otherwise, + * we end up with a zombie process. + */ + util_signalProcess(pid, SIGKILL); + if ((ret = util_collectProcess(pid, timeout)) != RETURN_OK) + { + CcspTraceError(("Still could not collect pid=%d after SIGKILL, ret=%d \n", pid, ret)); + /* this process is really stuck. Not much I can do now. + * Just leave it running I guess. */ + } + else + { + CcspTraceInfo(("collected pid %d after SIGKILL \n", pid)); + } + } + else + { + CcspTraceInfo(("collected pid %d\n", pid)); + } + return; +} + +int WanManager_DoStartApp(const char *appName, const char *cmdLineArgs) +{ + int pid = 0; + char command[BUFLEN_1024]; + if (NULL == appName) + { + CcspTraceError(("Application name is not given \n")); + return 0; + } + + CcspTraceInfo(("Starting %s - with parameters %s \n", appName, cmdLineArgs)); + + pid = LaunchApp(appName, cmdLineArgs); + /* Start application. */ + if (pid < 0) + { + CcspTraceError(("Failed to start %s application \n", appName)); + return 0; + } + + /* Get PID and return it. */ + return pid; +} + +void WanManager_DoStopApp(const char *appName) +{ + int pid; + + pid = util_getPidByName(appName); + if (pid > 0) + { + CcspTraceInfo(("Stopping %s \n", appName)); + util_signalProcess(pid, SIGTERM); + CollectApp(pid); + } +} + +int WanManager_DoRestartApp(const char *appName, const char *cmdLineArgs) +{ + if (NULL == appName) + { + CcspTraceError(("Application name is not given \n")); + return 0; + } + + CcspTraceInfo(("Restarting %s - with parameters %s \n", appName, cmdLineArgs)); + + /* Stop App if it is running. */ + if (WanManager_IsApplicationRunning(appName) == TRUE) + { + WanManager_DoStopApp(appName); + CcspTraceInfo(("App %s stopped \n", appName)); + } + /* Restart Application. */ + return WanManager_DoStartApp(appName, cmdLineArgs); +} + + +void WanManager_DoCollectApp(const char *appName) +{ + int pid; + + pid = util_getPidByName(appName); + if (pid > 0) + { + CcspTraceInfo(("Stopping %s zombie pid:%d\n", appName, pid)); + CollectApp(pid); + } +} + + +#ifdef FEATURE_IPOE_HEALTH_CHECK +UINT WanManager_StartIpoeHealthCheckService(const char *ifName) +{ + if (ifName == NULL) + { + CcspTraceError(("could not start %s. Invalid intfername name.\n", IHC_CLIENT_NAME)); + return 0; + } + + int IhcPid = 0; + char cmdArgs[BUFLEN_128] = {0}; + + snprintf(cmdArgs, BUFLEN_128, "-i %s", ifName); + CcspTraceInfo(("%s [%d]: Starting IHC with args - %s %s\n", __FUNCTION__, __LINE__, IHC_CLIENT_NAME, cmdArgs)); + + IhcPid = WanManager_DoStartApp(IHC_CLIENT_NAME, cmdArgs); + if (IhcPid == 0) + { + CcspTraceError(("%s [%d]: could not start %s", __FUNCTION__, __LINE__, IHC_CLIENT_NAME)); + return 0; + } + return IhcPid; +} + +ANSC_STATUS WanManager_StopIpoeHealthCheckService(UINT IhcPid) +{ + if (IhcPid == 0 ) + { + CcspTraceError(("Invalid PID %d. Cannot Stop IHC App.\n", IhcPid)); + return ANSC_STATUS_FAILURE; + } + util_signalProcess(IhcPid, SIGTERM); + CollectApp(IhcPid); + return ANSC_STATUS_SUCCESS; +} + +static ANSC_STATUS readIAPDPrefixFromFile(char *prefix, int buflen, int *plen, int *pltime, int *vltime) +{ + FILE *fp = NULL; + char *conffile = DHCP6C_RENEW_PREFIX_FILE; + ANSC_STATUS ret = ANSC_STATUS_SUCCESS; + char prefixAddr[128]; + int prefixLen = 0; + int prefLifeTime = 0; + int validLifeTime = 0; + + if ((fp = fopen(conffile,"r")) == NULL) + { + CcspTraceError(("Unable to open renew prefix file \n")); + ret = ANSC_STATUS_FAILURE; + } + else + { + /* Read the IA_PD information in the variable */ + fscanf(fp, "%s %d %d %d",prefixAddr, &prefixLen, &prefLifeTime, &validLifeTime); + CcspTraceInfo(("prefixAddr:%s buflen:%d prefixLen:%d prefLifeTime:%d validLifeTime:%d", + prefixAddr, buflen, prefixLen, prefLifeTime, validLifeTime)); + /* Copy the IA_PD prefix and delete the prefix file */ + if((prefix != NULL) && (strlen(prefixAddr) <= buflen)) + { + strncpy(prefix, prefixAddr, strlen(prefixAddr)); + *plen = prefixLen; + *pltime = prefLifeTime; + *vltime = validLifeTime; + } + else + { + ret = ANSC_STATUS_FAILURE; + } + fclose(fp); + unlink(conffile); + } + + return ret; +} +#endif + + + +/* * WanManager_GetDateAndUptime() */ +void WanManager_GetDateAndUptime( char *buffer, int *uptime ) +{ + struct timeval tv; + struct tm *tm; + struct sysinfo info; + char fmt[ 64 ], buf [64]; + + sysinfo( &info ); + gettimeofday( &tv, NULL ); + + if( (tm = localtime( &tv.tv_sec ) ) != NULL) + { + strftime( fmt, sizeof( fmt ), "%y%m%d-%T.%%06u", tm ); + snprintf( buf, sizeof( buf ), fmt, tv.tv_usec ); + } + + sprintf( buffer, "%s", buf); + + *uptime= info.uptime; +} + +uint32_t WanManager_getUpTime() +{ + struct sysinfo info; + sysinfo( &info ); + return( info.uptime ); +} diff --git a/source/WanManager/wanmgr_utils.h b/source/WanManager/wanmgr_utils.h new file mode 100644 index 00000000..180e2e45 --- /dev/null +++ b/source/WanManager/wanmgr_utils.h @@ -0,0 +1,155 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2015 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + + +/* ---- Include Files ---------------------------------------- */ + +#ifndef _WANMGR_UTILS_H_ +#define _WANMGR_UTILS_H_ +#include +#include +#include +#include +#include +#include +#include + + +#include "wanmgr_rdkbus_common.h" +//#include "ipc_msg.h" + + +#ifndef RETURN_OK +#define RETURN_OK 0 +#endif + +#ifndef RETURN_ERROR +#define RETURN_ERROR -1 +#endif + +#define IS_EMPTY_STRING(s) ((s == NULL) || (*s == '\0')) + +#define USECS_IN_MSEC 1000 +#define MSECS_IN_SEC 1000 + +#ifdef FEATURE_IPOE_HEALTH_CHECK +#define IHC_CLIENT_NAME "ipoe_health_check" +#define DHCP6C_RENEW_PREFIX_FILE "/tmp/erouter0.dhcpc6c_renew_prefix.conf" +#endif /* FEATURE_IPOE_HEALTH_CHECK */ + + +/*************************************************************************** + * @brief Utility function used to start application + * @param appName string contains the application name + * @param cmdLineArgs string contains arguments passed to application + * @return Return PID of the started application. + ***************************************************************************/ +int WanManager_DoStartApp (const char *appName, const char *cmdLineArgs); + +/*************************************************************************** + * @brief Utility function used to restart Application + * @param appName string contains the application name + * @param cmdLineArgs string contains arguments passed to application + * @return Return PID of the started application. + ***************************************************************************/ +int WanManager_DoRestartApp(const char *appName, const char *cmdLineArgs); + +/*************************************************************************** + * @brief Utility function used to stop Application + * @param appName string contains the application name + * @return None + ***************************************************************************/ +void WanManager_DoStopApp(const char *appName); + +/*************************************************************************** + * @brief Utility function used to clean zombie Application. + * @param appName string contains the application name + * @return None + ***************************************************************************/ +void WanManager_DoCollectApp(const char *appName); + +/*************************************************************************** + * @brief Utility function used to execute system command + * @param from string indicates caller + * @param cmd string indicates the commandline arguments + * @return None + ***************************************************************************/ +void WanManager_DoSystemAction(const char* from, char *cmd); + +/*************************************************************************** + * @brief Utility function used to execute system command + * @param from string indicates caller + * @param cmd string indicates the commandline arguments + * @return status of system() call. + ***************************************************************************/ +int WanManager_DoSystemActionWithStatus(const char* from, char *cmd); +/*************************************************************************** + * @brief API used to collect all the zombie processes + * @param pid pid of the application + * @return None + ****************************************************************************/ +void CollectApp(int pid); + + +#ifdef FEATURE_IPOE_HEALTH_CHECK +/*************************************************************************** + * @brief API used to start IPoE health check application. + * @return PID upon success else returns 0. + ***************************************************************************/ +UINT WanManager_StartIpoeHealthCheckService(); + +/*************************************************************************** + * @brief API used to atop IPoE health check application. + * @return ANSC_STATUS_SUCCESS upon success else returned error code. + ***************************************************************************/ +ANSC_STATUS WanManager_StopIpoeHealthCheckService(UINT IhcPid); +#endif //FEATURE_IPOE_HEALTH_CHECK + +/*************************************************************************** + * @brief API used to find path of the requested application + * @param name Name of the application + * @param buf Used to store the path + * @param len Buffer length + * @return pid of the launched application. + ****************************************************************************/ +int GetPathToApp(const char *name, char *buf, uint32_t len); + +/*************************************************************************** + * @brief API used to get data and uptime from system + * @param buffer to store date + * @param uptime to store uptime value + ****************************************************************************/ +void WanManager_GetDateAndUptime(char *buffer, int *uptime); + +/***************************************************************************************** + * @brief Utility API to get up time in seconds + * @return return uptime in seconds + ******************************************************************************************/ +uint32_t WanManager_getUpTime(); + + +int util_spawnProcess(const char *execName, const char *processInfo, int * processId); +int util_terminateProcessForcefully(int32_t pid); +int util_signalProcess(int32_t pid, int32_t sig); +int util_getPidByName(const char *name); +int util_getNameByPid(int pid, char *nameBuf, int nameBufLen); +int util_collectProcess(int pid, int timeout); +int util_runCommandInShellBlocking(char *command); + +#endif /* _WANMGR_UTILS_H_ */