Compare commits

...

135 Commits

Author SHA1 Message Date
Yalu Zhang
c5d06d65f5 Remove some files which have been deleted from devel branch 2020-12-23 15:08:30 +01:00
Yalu Zhang
d9d03436eb Rebase from devel branch 2020-12-23 15:01:16 +01:00
Yalu Zhang
5537b3ad37 Enchance the output of UBUS calls 2020-12-17 16:12:10 +01:00
Yalu Zhang
898b42cb8a Add log to show process id and thread id
Remove some code for Windows (WIN32 compilation option)
2020-12-15 15:22:34 +01:00
Yalu Zhang
e6086c918f Remove unused folder src/app/curl 2020-12-15 11:44:23 +01:00
Yalu Zhang
5200d7a3f9 Add log for thread creation 2020-12-15 11:28:45 +01:00
Yalu Zhang
7e454443b2 Make the process able to be stopped gracefully 2020-12-14 17:52:30 +01:00
Yalu Zhang
c5fc40069a Fix the UBUS asynchronisation issue
Send and receive of a ubus context MUST happens from one thread, otherwise it causes hanging.
So handle ubus, uart and callback in one single thread.
2020-12-11 17:37:38 +01:00
Yalu Zhang
87ebd9a601 Send digits to endptmngr during a connected call by ubus call 2020-12-08 18:23:04 +01:00
Yalu Zhang
a3d0ce3c67 Remove MEDIA5 support 2020-12-08 12:49:28 +01:00
Yalu Zhang
819461dc5b An incoming call can be cancelled by the remote caller 2020-12-04 15:33:03 +01:00
Yalu Zhang
f532bac520 Notify asterisk when a dect handset hangs up
Also remove appaudio
2020-12-03 18:21:23 +01:00
Yalu Zhang
a6269fa0d4 get_call_id(): get call-id by handset id 2020-12-02 17:13:16 +01:00
Yalu Zhang
b743353ba1 Rlease an outgoing call properly when the remote peer terminates first 2020-12-02 15:53:53 +01:00
Yalu Zhang
e0ae025ff1 Remove hardcode term_id and pcm_id from cmbsevent_onCallAnswered() 2020-12-01 16:17:25 +01:00
Yalu Zhang
da55bf9b46 Send ubus event and call endpt call for an outgoing call from a handset
For example, { "dect": {"terminal":"0","dialed":"7001"} } // dial 7001
ubus call endpt call "{'terminal': 1, 'add': 0, 'release': -1}"
2020-12-01 12:09:13 +01:00
Yalu Zhang
fefe1b1b20 Send ubus event { "dect": {"handset":"present"} } whenever hook state changes 2020-11-30 14:53:46 +01:00
Yalu Zhang
dcd22a03c5 Fix some compiling warnings 2020-11-27 17:48:52 +01:00
Yalu Zhang
4aa7bcb4ec Notify endptmngr via UBUS calls and events when the handset answers a call 2020-11-27 16:02:22 +01:00
Yalu Zhang
263a5ab611 Remove unused folder and files: app/Jsystem 2020-11-26 15:40:02 +01:00
Yalu Zhang
7bf24c37ce Implementation of 'ubus call dect call {...}'
- ubus call dect call '{ "terminal": 1, "add": 0, "cid": "+46701234567" }'
- ubus call dect call '{ "terminal": 1, "release": 0 }'
2020-11-24 16:59:40 +01:00
Yalu Zhang
0eeeeff94b Add error code support in libdect
Return the error code and string from libdect instead of errno
2020-11-20 10:53:16 +01:00
Yalu Zhang
949c386359 Add libdect and implement enable/disable registration 2020-11-19 17:33:26 +01:00
Yalu Zhang
da14aefe20 Add uloop initialization 2020-11-19 14:16:07 +01:00
Yalu Zhang
8ce8d7cf84 Adjust main() function to fit dectmngr
Also remove some unused files and folders.
2020-11-18 18:04:36 +01:00
Yalu Zhang
a564e55cfc Add ubus functions 2020-11-18 16:20:57 +01:00
Yalu Zhang
1574a35631 Rename folder test to app 2020-11-17 12:06:02 +01:00
Yalu Zhang
530cca802a Remove unnecessary dependencies in package dectmngr 2020-11-13 16:32:38 +01:00
Anjan Chanda
d7f6c6a9f7 ieee1905: 2.1.0 2020-11-13 16:32:38 +01:00
Jakob Olsson
1416a64348 ieee1905: 20.0.30 - release-5.3 branch 2020-11-13 16:32:38 +01:00
Jakob Olsson
611d6bcee9 Revert "ieee1905: 20.0.30"
This reverts commit f01bd18ffc.
2020-11-13 16:32:38 +01:00
Jakob Olsson
8dba98e282 ieee1905: 20.0.30 2020-11-13 16:32:38 +01:00
Omar Kallel
febad86760 icwmp: 5.0-2020-10-13 2020-11-13 16:32:38 +01:00
Amin Ben Ramdhane
a56f8d7be9 bbf: 2.5-2020-10-26 2020-11-13 16:32:38 +01:00
Arun Muthusamy
5ea8207cef Add Libreswan package 2020-11-13 16:32:38 +01:00
Amin Ben Ramdhane
1dfba64bde bbf: 2.5-2020-10-23 2020-11-13 16:32:38 +01:00
Sukru Senli
bcbc7999cd iop: config: selectm miniupnpc by default 2020-11-13 16:32:38 +01:00
Jakob Olsson
5c78b83ac8 map-1905: 0.0.13 2020-11-13 16:32:38 +01:00
Rahul
ef8c6eb8c9 qosmngr: add log
Syslog added to log non-availability of traffic policing on the wan
port on 63138, this is a chip level limitation.
2020-11-13 16:32:38 +01:00
Rahul
7e7867becf qosmngr: add support for dhcp option as classification criteria
DHCP option value 60, 61 and 77 can now be used to identify lan
clients. Details of UCI as follows:

config classify
    option src_vendor_class_id 'abc' // DHCP option 60.
    option dst_vendor_class_id 'abc' // DHCP option 60.
    option src_client_id 'xyz'       // DHCP option 61
    option dst_client_id 'xyz'       // DHCP option 61
    option src_user_class_id 'dfg'   // DHCP option 77
    option dst_user_class_id 'dfg'   // DHCP option 77
2020-11-13 16:32:38 +01:00
Rahul
a03a91f858 qosmngr: add support for upstream policing on dg400prime
This patch adds support for upstream policing on dg400prime.
Downstream policing still seems to be an issue for which ticket
has been re-opened on broadcom.

Test:
Upstream policing test script passes on both panther and dg400prime.
2020-11-13 16:32:38 +01:00
Amin Ben Ramdhane
370d03eaf6 bbf: fix SentOption segfault issue 2020-11-13 16:32:38 +01:00
Amin Ben Ramdhane
e142514135 bbf: fix DHCPv4 MaxAddress 2020-11-13 16:32:38 +01:00
Sukru Senli
7e19d3550a bbf: 2.4-2020-10-10 2020-11-13 16:32:38 +01:00
Sukru Senli
b0cc223750 icwmp: keep cwmp session backup xml file over upgrade 2020-11-13 16:32:38 +01:00
Omar Kallel
bf8c210f3b Rename uci notify options && remove ubus call tr069 notify from the init 2020-11-13 16:32:38 +01:00
Omar Kallel
493d8b05cd icwmp: 09-10-2020 2020-11-13 16:32:38 +01:00
Omar Kallel
13b5958852 Add new notification feature & delete icwmp_notifd 2020-11-13 16:32:38 +01:00
Sukru Senli
02ff58d9c2 iop: select rsync; needed by upgrade script
rsync is GPLv3 so we need to make upgrade script independent of it
2020-11-13 16:32:38 +01:00
Amin Ben Ramdhane
59dc9afe0f bbf: 2.4-2020-10-09 2020-11-13 16:32:38 +01:00
Omar
70f9fc7854 icwmp: 5.0-2020-10-09 2020-11-13 16:32:38 +01:00
sverma
da43c27174 wfadatad: Misc Fixes.
* Added mandatory profile-2 tlvs
	* Topology query responded only when it's having map-2 provile TLV
	* Added support for ieee1905.neighbor event
2020-11-13 16:32:38 +01:00
Raphael Derensy
82b06b2365 iop: select atftp and atftpd as modules 2020-11-13 16:32:38 +01:00
vdutta
ad64108ada map-1905: Fix parsing of channel preference tlv 2020-11-13 16:32:38 +01:00
nevadita.chatterjee
9108ff44bc map-topology:Added version 2020-11-13 16:32:38 +01:00
Omar Kallel
0915525fd0 icwmp: 5.0-2020-10-07 2020-11-13 16:32:38 +01:00
Omar Kallel
958ff29190 bbf: 2.4-2020-10-07 2020-11-13 16:32:38 +01:00
Sukru Senli
cc32f540d4 iop: deselect some gplv3 packages 2020-11-13 16:32:38 +01:00
Jakob Olsson
b2823a6b1d rulengd: add regex match to event name 2020-11-13 16:32:38 +01:00
Sukru Senli
d3d0584056 icwmp: remove unnecessary parts from init script 2020-11-13 16:32:38 +01:00
vdutta
8372c9c7ad ieee1905: Fix crash in ex400 2020-11-13 16:32:38 +01:00
vdutta
faa39d1d15 map-1905: Multiple fixes
- Change structure for countrycode in CAC capability
 - Fix segfault in timestamp tlv
2020-11-13 16:32:38 +01:00
Omar Kallel
e0b38245e1 bbf: 2020-10-02 2020-11-13 16:32:38 +01:00
Omar Kallel
f40d078a3b icwmp: 2020-10-02 2020-11-13 16:32:38 +01:00
Jakob Olsson
87cf33663c wifimngr: 8.2.9 2020-11-13 16:32:38 +01:00
Jakob Olsson
99e5dd1443 easy-soc-libs: 5.3.15 2020-11-13 16:32:38 +01:00
Yalu Zhang
7f53336a83 Rename package dspg_test_app to dectmngr
Also rename cmbs_tcx to dectmngr
2020-11-13 15:21:01 +01:00
Yalu Zhang
32479eab89 Update makefile to generate libdect.so 2020-10-22 11:58:17 +02:00
Yalu Zhang
7e607d8e09 Add .config file which enables ALSA kernel modules, libraries and utilities
arecord and aplay can be used to record and play during a call between DECT phone and CPE
which is initiated by pressing 'o' from the test application

~/git/iopsyswrt$ cat .config|egrep -i "alsa|sound|audio|usb"|grep -v "not set"
CONFIG_DEFAULT_asterisk-sounds=y
CONFIG_AUDIO_SUPPORT=y
CONFIG_USB_SUPPORT=y
CONFIG_BUSYBOX_CONFIG_LSUSB=y
CONFIG_PACKAGE_alsa-lib=y
CONFIG_PACKAGE_libffmpeg-audio-dec=y
CONFIG_PACKAGE_libusb-1.0=y
CONFIG_PACKAGE_libusb-compat=y
CONFIG_PACKAGE_asterisk-sounds=y
CONFIG_PACKAGE_alsa-utils=y
CONFIG_PACKAGE_alsa-utils-seq=y
CONFIG_PACKAGE_alsa-utils-tests=y
CONFIG_PACKAGE_usb-modeswitch=y
CONFIG_PACKAGE_usbreset=y

iopsyswrt/build_dir/target-arm_xscale_musl_eabi/linux-iopsys-brcm63xx-arm/linux-dev_iopsys_eu_broadcom_bcmlinux_git-HEAD$ cat .config |egrep -i "alsa|sound|audio|usb"|grep -v "not set"|grep -v "#"
CONFIG_SOUND=y
CONFIG_SOUND_OSS_CORE=y # Perhaps not needed
CONFIG_SOUND_OSS_CORE_PRECLAIM=y # Perhaps not needed
CONFIG_SND_USB=y
CONFIG_USB_OHCI_LITTLE_ENDIAN=y
CONFIG_USB_SUPPORT=y
CONFIG_USB_COMMON=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB=y
CONFIG_USB_DEFAULT_PERSIST=y
2020-10-14 14:35:53 +02:00
Yalu Zhang
7528a4a11f Improve load_sound_modules.sh a bit 2020-10-14 12:01:41 +02:00
Yalu Zhang
77b306d598 Add a script to load/unload Linux sound kermodules 2020-10-14 11:55:52 +02:00
Yalu Zhang
575a88afdd Make it easier to compile in Linux other than iopsyswrt 2020-10-14 11:55:52 +02:00
Yalu Zhang
6741df8952 Remove unused source files
- folder frame/vone
- cfr_coma.c
2020-10-14 11:55:52 +02:00
Yalu Zhang
60f9815721 Remove unused source files in the folder frame/vone 2020-10-08 10:46:27 +02:00
Yalu Zhang
4cab43e30d Add DSPG test application version 4.13_build_6rc7
The contents in foler src/ are imported from DSPG's tarball.
2020-10-01 17:07:01 +02:00
Rahul
342bec0b25 qosmngr: add support for traffic policing
Support for traffic policing added to allow configuration of
ingress rate limiting.

Test (on panther):
- ingress rate limiting on per lan port basis for US traffic.
- ingress rate limiting on wan port for DS traffic.
- when ingress rate limiting is applied on traffic in one direction,
  then traffic in other direction remains un-affected, that is, if
  ingress rate limiting is applied in DS, then US traffic on the port
  is unaffected

Note: Autotest are ready and will be merge for now with the tag not_ready.
Once devel is ready or if we decide to merge this to release-5.3, the same
can be tagged ready and executed as part of nightly suite.
2020-09-30 09:10:39 +02:00
Anjan Chanda
3942b33e1e wifimngr: 8.2.8 2020-09-29 21:51:19 +02:00
Anjan Chanda
3c3608e87c easy-soc-libs: 5.3.14 2020-09-29 21:51:04 +02:00
Amin Ben Ramdhane
aaf0029500 bbf: 2.4-2020-09-29 2020-09-29 19:20:14 +01:00
Amin Ben Ramdhane
7b80bcf104 icwmp: 5.0-2020-09-29 2020-09-29 19:18:18 +01:00
Raphael Derensy
f419a955f6 iop: select vsftpd-tls as module 2020-09-29 11:40:08 +02:00
Suru Dissanaike
d644ce7be6 iop: config, change rsync to module 2020-09-28 11:10:32 +02:00
Amin Ben Ramdhane
887ff49b95 bbf: 2.3-2020-09-26 2020-09-26 17:30:01 +01:00
Amin Ben Ramdhane
9c6533f45f bbf: 2.2-2020-09-24 2020-09-24 16:15:38 +01:00
Jakob Olsson
08f903e2c1 wifimngr: 8.2.7 2020-09-24 15:02:56 +02:00
Jakob Olsson
833837cea1 easy-soc-libs: 5.3.9 2020-09-24 15:01:22 +02:00
vdutta
dabf83ea1d uspd: B#3272 improvements in resolving paths 2020-09-24 13:48:33 +05:30
Anjan Chanda
0e6146f105 map-topology: 1.5.5 - notify topology change event 2020-09-24 09:33:04 +02:00
Amin Ben Ramdhane
220a4efbf7 Ticket refs #3228: QEMU - ICWMP is segfaulting
Fix missing objects
2020-09-23 19:21:14 +01:00
vdutta
e5d8d81019 ieee1905: Get auth mode from bss.security 2020-09-23 19:07:59 +05:30
vdutta
70442e891f ieee1905: Remove redundant info from ubus objects 2020-09-22 19:52:21 +05:30
Sukru Senli
ec021d54f5 iop: genconfig: comment out mediatek open parts 2020-09-22 12:33:08 +02:00
Amin Ben Ramdhane
421e633094 bbf: 2.1-2020-09-21 2020-09-21 18:16:25 +01:00
Jakob Olsson
068308f052 rearrange start orders for topology and ieee1905 2020-09-21 16:15:39 +02:00
Omar Kallel
8809a7aba7 bbf: fix segfault 2020-09-21 14:05:15 +02:00
Omar Kallel
7575dccbc0 icwmp: 5.0-2020-09-21 2020-09-21 14:04:53 +02:00
Jakob Olsson
871831fdac wfadatad: use service_running hook to wait for ieee1905 object 2020-09-21 09:12:27 +02:00
Amin Ben Ramdhane
db41d298c3 bbf: 2.0-2020-09-21 2020-09-21 09:09:54 +02:00
Jakob Olsson
ad372152d5 ieee1905: config trigger to reload 2020-09-21 09:01:11 +02:00
Jakob Olsson
926648b090 ieee1905: change start order from 99 to 13 2020-09-21 08:49:34 +02:00
Jakob Olsson
240bdc5bb8 wfadatad: wait up to 2 seconds if ieee1905 is not up before start 2020-09-21 08:49:14 +02:00
Amin Ben Ramdhane
45e0b4f2ed bbf: 2.0-2020-09-18 2020-09-18 15:19:14 +01:00
Jakob Olsson
332a90d087 map-topology: iterate til ieee1905 object is up 2020-09-18 16:13:32 +02:00
Anjan Chanda
09937f540a ieee1905d: enable map plugin in default config 2020-09-18 15:17:57 +02:00
Anjan Chanda
af8f27ef65 wfadatad: 2.3.0 2020-09-18 15:13:12 +02:00
Jakob Olsson
8a799f183b easy-soc-libs: libeasy: include debug.h 2020-09-18 14:34:00 +02:00
sverma
2dbf38c06c wfadatad: Changes UBUS objects name 2020-09-18 13:35:17 +02:00
Anjan Chanda
b1fcc12599 wifimngr: 8.2.3 2020-09-18 13:31:04 +02:00
Anjan Chanda
9041f616e7 easy-soc-libs: 5.3.3 2020-09-18 13:30:32 +02:00
Anjan Chanda
dc14b18428 map-topology: 1.5.1 2020-09-18 13:29:33 +02:00
Amin Ben Ramdhane
e41f973953 xmpp, udpecho, twamp: compile with fPIC 2020-09-18 12:07:17 +02:00
vdutta
9889814f0b uspd: Optimizations to reduce high cpu usages 2020-09-17 16:22:17 +05:30
Sukru Senli
2922f211f7 bulkdata: compile with fPIC 2020-09-16 10:02:59 +02:00
Sukru Senli
22dd43c79e icwmp: set userid empty in cwmp config; it will be filled by uci-default 2020-09-16 08:22:07 +02:00
Omar Kallel
478c34d48f icwmp: add the file /lib/upgrade/keep.d/icwmp when installing icwmp 2020-09-15 16:25:26 +02:00
Sukru Senli
49f46ef075 icwmp: 5.0-2020-09-15 2020-09-15 16:18:16 +02:00
Sukru Senli
03dc0ebb72 bbf: 2.0-2020-09-15 2020-09-15 16:11:15 +02:00
Sukru Senli
fa44657557 move trx69 packages out of trx69 folder 2020-09-14 18:28:00 +02:00
nevadita.chatterjee
42a3ed939a map-topology: Config file change 2020-09-14 18:27:00 +02:00
Markus Gothe
6e35356954 Fix gryphon LED module crash.
Update gryphon LED module to work with Linux 4.1
and not to crash when 'gpiod_get_index()' fails.

Change-Id: I27fcbe3ad9dbc755eabdd3f2120544b171b07885
2020-09-14 18:26:58 +02:00
Roman Azarenko
7978a656a7 iop: generate_tarballs: bcmkernel: add symlink if missing, partially fix shellcheck warnings 2020-09-14 18:26:56 +02:00
Sukru Senli
17322c3cba iop: config: select icwmp and bulkdata 2020-09-14 18:26:43 +02:00
Amin Ben Ramdhane
890b627139 icwmp: 5.0-2020-09-10 2020-09-14 18:22:21 +02:00
Amin Ben Ramdhane
0ad28b756b Ticket #2910: Separate BBF packages to their own packages with their own config files 2020-09-14 18:22:21 +02:00
Omar Kallel
309c26f4b0 icwmp: 09-09-2020 2020-09-14 18:22:21 +02:00
Omar Kallel
df4e11ae30 icwmp: Active notification 08/09/2020 2020-09-14 18:22:21 +02:00
Amin Ben Ramdhane
9de4a18a20 bbf: 2.0-2020-09-08 2020-09-14 18:22:21 +02:00
Sukru Senli
bfcc877a6a Revert "bbf: 1.9-2020-09-07"
This reverts commit 24a82ab61c.
2020-09-14 18:22:21 +02:00
Suru Dissanaike
d9527a5a1a icwmp: userid fix release, missing check if value is already present 2020-09-14 11:44:38 +02:00
Jakob Olsson
e707922d29 map-topology: override log func to supress prints 2020-09-14 09:06:53 +02:00
vdutta
cfc2e6d9eb obsupa: Increase ubus timeout to 10s 2020-09-11 16:52:41 +05:30
Jakob Olsson
0ec3e0eae8 map-topology: implement service discovery via dns-sd 2020-09-10 17:09:38 +02:00
Sukru Senli
38c4c7ded0 questd: 5.1.12: MAX_CLIENT increased to 256 2020-09-08 16:29:33 +02:00
Sukru Senli
24a82ab61c bbf: 1.9-2020-09-07 2020-09-08 12:55:20 +02:00
vdutta
5977ec807c uspd: Align with new gitlab ci 2020-09-08 15:47:23 +05:30
419 changed files with 352362 additions and 1522 deletions

View File

@@ -16,12 +16,4 @@ config BBF_TR143
bool "Compile with tr143 diagnostics features"
default y
config BBF_TR157
bool "Compile with tr157 bulkdata collector features"
default y
config BBF_TR064
bool "Compile with tr064 features"
default n
endif

View File

@@ -5,11 +5,11 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=libbbfdm
PKG_VERSION:=1.9-2020-09-01
PKG_VERSION:=3.2.8
PKG_FIXUP:=autoreconf
PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/bbf.git
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=725981c900e0844107a857b53f636ae0a3a92eda
PKG_SOURCE_VERSION:=8c25b2ff8728a0c184404ab45c4d6b3c340ed52d
PKG_RELEASE=$(PKG_SOURCE_VERSION)
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
@@ -44,7 +44,7 @@ define Package/libbbf_api/description
endef
define Package/libbbfdm/description
Library contains the data model tree. It includes TR181, TR104, TR143, TR157 and TR064 data models
Library contains the data model tree. It includes TR181, TR104 and TR143 data models
endef
USE_LOCAL=$(shell ls ./src/ 2>/dev/null >/dev/null && echo 1)
@@ -74,16 +74,6 @@ CONFIGURE_ARGS += \
--enable-tr143
endif
ifeq ($(CONFIG_BBF_TR157),y)
CONFIGURE_ARGS += \
--enable-tr157
endif
ifeq ($(CONFIG_BBF_TR064),y)
CONFIGURE_ARGS += \
--enable-tr064
endif
ifeq ($(CONFIG_PACKAGE_libopenssl),y)
CONFIGURE_ARGS += \
--enable-libopenssl
@@ -102,20 +92,23 @@ endef
define Package/libbbfdm/install
$(INSTALL_DIR) $(1)/lib
$(CP) $(PKG_BUILD_DIR)/bin/.libs/libbbfdm.so* $(1)/lib/
$(INSTALL_DIR) $(1)/etc/bbfdm
$(INSTALL_DIR) $(1)/etc/bbfdm/json
$(INSTALL_CONF) $(PKG_BUILD_DIR)/config/dmmap $(1)/etc/bbfdm
$(INSTALL_DIR) $(1)/usr/share/bbfdm
$(CP) $(PKG_BUILD_DIR)/scripts/functions $(1)/usr/share/bbfdm
$(INSTALL_DIR) $(1)/etc/bbfdm
$(INSTALL_DIR) $(1)/etc/bbfdm/json
$(INSTALL_DIR) $(1)/usr/lib/bbfdm
endef
define Package/libbbfdm/prerm
#!/bin/sh
rm -rf /etc/bbfdm/*
exit 0
endef
define Build/InstallDev
$(INSTALL_DIR) $(1)/usr/include/libbbfdm
$(INSTALL_DIR) $(1)/usr/include/libbbf_api
$(CP) $(PKG_BUILD_DIR)/*.h $(1)/usr/include/libbbfdm/
$(CP) $(PKG_BUILD_DIR)/dmtree/tr181/*.h $(1)/usr/include/libbbfdm/
$(CP) $(PKG_BUILD_DIR)/dmtree/tr157/*.h $(1)/usr/include/libbbfdm/
$(CP) $(PKG_BUILD_DIR)/libbbf_api/*.h $(1)/usr/include/libbbf_api/
$(INSTALL_DIR) $(1)/usr/lib
$(CP) $(PKG_BUILD_DIR)/bin/.libs/libbbfdm.{a,so*} $(1)/usr/lib/

44
bulkdata/Makefile Executable file
View File

@@ -0,0 +1,44 @@
#
# Copyright (C) 2020 iopsys Software Solutions AB
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=bulkdata
PKG_VERSION:=1.0.0
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
include $(INCLUDE_DIR)/package.mk
define Package/$(PKG_NAME)
SECTION:=utils
CATEGORY:=Utilities
SUBMENU:=TRx69
TITLE:=BBF BulkData Collection
DEPENDS:=+libubus +libuci +libubox +libjson-c +libcurl +curl +libblobmsg-json +libbbfdm +libbbf_api
endef
define Package/$(PKG_NAME)/description
BBF BulkData Collection
endef
define Build/Prepare
$(CP) ./src/* $(PKG_BUILD_DIR)/
endef
TARGET_CFLAGS += \
-D_GNU_SOURCE
define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/bulkdatad $(1)/usr/sbin/
$(INSTALL_DIR) $(1)/usr/lib/bbfdm
$(INSTALL_BIN) $(PKG_BUILD_DIR)/*.so $(1)/usr/lib/bbfdm
$(CP) ./files/* $(1)/
endef
$(eval $(call BuildPackage,$(PKG_NAME)))

View File

@@ -0,0 +1,43 @@
config bulkdata 'bulkdata'
option enable '0'
#Log levels: Critical=0, Warning=1, Notice=2, Info=3, Debug=4
option log_level '3'
config profile
option profile_id '1'
option enable '0'
option name ''
option nbre_of_retained_failed_reports '0'
option protocol 'http'
option encoding_type ''
option reporting_interval '86400'
option time_reference '0'
option csv_encoding_field_separator ','
option csv_encoding_row_separator '
'
option csv_encoding_escape_character '"'
option csv_encoding_report_format 'column'
option csv_encoding_row_time_stamp 'unix'
option json_encoding_report_format 'objecthierarchy'
option json_encoding_report_time_stamp 'unix'
option http_url ''
option http_username ''
option http_password ''
option http_compression 'none'
option http_method 'post'
option http_use_date_header '1'
option http_retry_enable '0'
option http_retry_minimum_wait_interval '5'
option http_retry_interval_multiplier '2000'
option http_persist_across_reboot '0'
config profile_parameter
option profile_id '1'
option name ''
option reference ''
config profile_http_request_uri_parameter
option profile_id '1'
option name ''
option reference ''

View File

@@ -0,0 +1,34 @@
#!/bin/sh /etc/rc.common
# Bulkdata Software
# Copyright (C) 2020 iopsys Software Solutions AB
# Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
START=99
STOP=10
USE_PROCD=1
PROG="/usr/sbin/bulkdatad"
start_service() {
local bulkdata_enable=`uci -q get bulkdata.bulkdata.enable`
if [ "$bulkdata_enable" = "1" ]; then
procd_open_instance
procd_set_param command "$PROG"
procd_set_param respawn "3" "7" "0"
procd_close_instance
fi
}
boot() {
start
}
reload_service() {
stop
start
}
service_triggers()
{
procd_add_reload_trigger bulkdata
}

23
bulkdata/src/Makefile Normal file
View File

@@ -0,0 +1,23 @@
PROG = bulkdatad
LIB = libbulkdata.so
PROG_OBJS = bulkdata.o common.o config.o http.o log.o report.o times.o buci.o
LIB_OBJS = datamodel.o
PROG_CFLAGS = $(CFLAGS) -Wall -Werror -fPIC
PROG_LDFLAGS = $(LDFLAGS) -lubus -luci -lubox -ljson-c -lcurl -lblobmsg_json -lbbfdm -lbbf_api
LIB_LDFLAGS = $(LDFLAGS) -lbbf_api
%.o: %.c
$(CC) $(PROG_CFLAGS) $(FPIC) -c -o $@ $<
all: $(PROG) $(LIB)
$(PROG): $(PROG_OBJS)
$(CC) $(PROG_CFLAGS) -o $@ $^ $(PROG_LDFLAGS)
$(LIB): $(LIB_OBJS)
$(CC) $(PROG_CFLAGS) $(LIB_LDFLAGS) -shared -o $@ $^
clean:
rm -f *.o $(PROG) $(LIB)

265
bulkdata/src/buci.c Normal file
View File

@@ -0,0 +1,265 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Copyright (C) 2020 iopsys Software Solutions AB
* Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
*
*/
#include <strings.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <errno.h>
#include <unistd.h>
#include <ctype.h>
#include "buci.h"
struct uci_context *uci_ctx = NULL;
int buci_init(void)
{
uci_ctx = uci_alloc_context();
if (!uci_ctx) {
return -1;
}
return 0;
}
int buci_fini(void)
{
if (uci_ctx) {
uci_free_context(uci_ctx);
}
return 0;
}
static bool buci_validate_section(const char *str)
{
if (!*str)
return false;
for (; *str; str++) {
unsigned char c = *str;
if (isalnum(c) || c == '_')
continue;
return false;
}
return true;
}
static int buci_init_ptr(struct uci_context *ctx, struct uci_ptr *ptr, char *package, char *section, char *option, char *value)
{
memset(ptr, 0, sizeof(struct uci_ptr));
/* value */
if (value) {
ptr->value = value;
}
ptr->package = package;
if (!ptr->package)
goto error;
ptr->section = section;
if (!ptr->section) {
ptr->target = UCI_TYPE_PACKAGE;
goto lastval;
}
ptr->option = option;
if (!ptr->option) {
ptr->target = UCI_TYPE_SECTION;
goto lastval;
} else {
ptr->target = UCI_TYPE_OPTION;
}
lastval:
if (ptr->section && !buci_validate_section(ptr->section))
ptr->flags |= UCI_LOOKUP_EXTENDED;
return 0;
error:
return -1;
}
struct uci_section *buci_walk_section(char *package, char *section_type, struct uci_section *prev_section)
{
struct uci_ptr ptr;
struct uci_element *e;
struct uci_section *next_section;
if (section_type == NULL) {
if (prev_section) {
e = &prev_section->e;
if (e->list.next == &prev_section->package->sections)
return NULL;
e = container_of(e->list.next, struct uci_element, list);
next_section = uci_to_section(e);
return next_section;
}
else {
if (buci_init_ptr(uci_ctx, &ptr, package, NULL, NULL, NULL)) {
return NULL;
}
if (uci_lookup_ptr(uci_ctx, &ptr, NULL, true) != UCI_OK) {
return NULL;
}
if (ptr.p->sections.next == &ptr.p->sections)
return NULL;
e = container_of(ptr.p->sections.next, struct uci_element, list);
next_section = uci_to_section(e);
return next_section;
}
}
else {
struct uci_list *ul, *shead = NULL;
if (prev_section) {
ul = &prev_section->e.list;
shead = &prev_section->package->sections;
}
else {
if (buci_init_ptr(uci_ctx, &ptr, package, NULL, NULL, NULL)) {
return NULL;
}
if (uci_lookup_ptr(uci_ctx, &ptr, NULL, true) != UCI_OK) {
return NULL;
}
ul = &ptr.p->sections;
shead = &ptr.p->sections;
}
while (ul->next != shead) {
e = container_of(ul->next, struct uci_element, list);
next_section = uci_to_section(e);
if (strcmp(next_section->type, section_type) == 0)
return next_section;
ul = ul->next;
}
return NULL;
}
return NULL;
}
void buci_print_list(struct uci_list *uh, char **val, char *delimiter)
{
struct uci_element *e;
static char buffer[512];
char *buf = buffer;
*buf = '\0';
uci_foreach_element(uh, e) {
if (*buf) {
strcat(buf, delimiter);
strcat(buf, e->name);
}
else {
strcpy(buf, e->name);
}
}
*val = buf;
}
struct uci_element *buci_lookup_list(struct uci_list *list, const char *name)
{
struct uci_element *e;
uci_foreach_element(list, e) {
if (!strcmp(e->name, name))
return e;
}
return NULL;
}
int uci_lookup_ptr_bysection(struct uci_context *ctx, struct uci_ptr *ptr, struct uci_section *section, char *option, char *value)
{
struct uci_element *e;
memset(ptr, 0, sizeof(struct uci_ptr));
ptr->package = section->package->e.name;
ptr->section = section->e.name;
ptr->option = option;
ptr->value = value;
ptr->flags |= UCI_LOOKUP_DONE;
ptr->p = section->package;
ptr->s = section;
if (ptr->option) {
e = buci_lookup_list(&ptr->s->options, ptr->option);
if (!e)
return UCI_OK;
ptr->o = uci_to_option(e);
ptr->last = e;
ptr->target = UCI_TYPE_OPTION;
}
else {
ptr->last = &ptr->s->e;
ptr->target = UCI_TYPE_SECTION;
}
ptr->flags |= UCI_LOOKUP_COMPLETE;
return UCI_OK;
}
char *buci_get_value_bysection(struct uci_section *section, char *option)
{
struct uci_ptr ptr;
char *val = "";
if (uci_lookup_ptr_bysection(uci_ctx, &ptr, section, option, NULL) != UCI_OK) {
return val;
}
if (!ptr.o)
return val;
if(ptr.o->type == UCI_TYPE_LIST) {
buci_print_list(&ptr.o->v.list, &val, " ");
return val;
}
if (ptr.o->v.string)
return ptr.o->v.string;
else
return val;
}
char *buci_get_value(char *package, char *section, char *option)
{
struct uci_ptr ptr;
char *val = "";
if (!section || !option)
return val;
if (buci_init_ptr(uci_ctx, &ptr, package, section, option, NULL)) {
return val;
}
if (uci_lookup_ptr(uci_ctx, &ptr, NULL, true) != UCI_OK) {
return val;
}
if (!ptr.o)
return val;
if(ptr.o->type == UCI_TYPE_LIST) {
buci_print_list(&ptr.o->v.list, &val, " ");
return val;
}
if (ptr.o->v.string)
return ptr.o->v.string;
else
return val;
}

31
bulkdata/src/buci.h Normal file
View File

@@ -0,0 +1,31 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Copyright (C) 2020 iopsys Software Solutions AB
* Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
*
*/
#ifndef __BUCI_H
#define __BUCI_H
#include <uci.h>
int buci_init(void);
int buci_fini(void);
struct uci_section *buci_walk_section(char *package, char *section_type, struct uci_section *prev_section);
void buci_print_list(struct uci_list *uh, char **val, char *delimiter);
struct uci_element *buci_lookup_list(struct uci_list *list, const char *name);
int uci_lookup_ptr_bysection(struct uci_context *ctx, struct uci_ptr *ptr, struct uci_section *section, char *option, char *value);
char *buci_get_value_bysection(struct uci_section *section, char *option);
char *buci_get_value(char *package, char *section, char *option);
#define buci_foreach_section(package, section_type, section) \
for (section = buci_walk_section(package, section_type, NULL); \
section != NULL; \
section = buci_walk_section(package, section_type, section))
#endif //__BUCI_H

144
bulkdata/src/bulkdata.c Normal file
View File

@@ -0,0 +1,144 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Copyright (C) 2020 iopsys Software Solutions AB
* Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
* Omar Kallel <omar.kallel@pivasoftware.com>
*/
#include <stdio.h>
#include <string.h>
#include <libubox/uloop.h>
#include "http.h"
#include "config.h"
#include "log.h"
#include "common.h"
#include "report.h"
#include "times.h"
#include "bulkdata.h"
struct bulkdata bulkdata_main = {0};
int profiles_number = 0;
void bulkdata_profile_cb(struct uloop_timeout *timeout);
int get_retry_period(int min)
{
srand(time(NULL));
return rand()%min + min;
}
static void bulkdata_run_profiles(struct bulkdata *bulkdata)
{
unsigned int next_period;
int i = 0;
for (i = 0; i < profiles_number; i++) {
bulkdata->profile[i].utimer.cb = bulkdata_profile_cb;
LIST_HEAD(failedreports);
bulkdata->profile[i].failed_reports = &failedreports;
next_period = get_next_period(bulkdata->profile[i].time_reference, bulkdata->profile[i].reporting_interval);
bulkdata_log(SINFO, "The session of profile_id %d will be start in %d sec", bulkdata->profile[i].profile_id, next_period);
uloop_timeout_set(&bulkdata->profile[i].utimer, next_period * 1000);
}
}
int http_send_report(struct profile *profile, char *report)
{
char *msg_in = NULL;
int http_code;
http_client_init(profile);
bulkdata_log(SINFO, "Send the report of profile_id %d to Bulkdata Collector", profile->profile_id);
http_code = http_send_message(profile, report, strlen(report), &msg_in);
http_client_exit();
return http_code;
}
void bulkdata_profile_cb(struct uloop_timeout *timeout)
{
struct profile *profile;
unsigned int http_code, retry_period;
char *report = NULL;
profile = container_of(timeout, struct profile, utimer);
time_t now = time(NULL);
bulkdata_log(SINFO, "New session of profile_id %d started", profile->profile_id);
if(profile->retry_count == 0 || profile->next_retry > now || !profile->http_retry_enable) //Perdiodic execution
create_encoding_bulkdata_report(profile, &report);
else
create_failed_report(profile, &report);
bulkdata_log(SDEBUG, "The content of the profile_id report %d is :\n==========\n%s\n==========\n", profile->profile_id, report);
http_code= http_send_report(profile, report);
if(http_code != 200){
if(profile->retry_count == 0 || profile->next_retry > now || !profile->http_retry_enable) { //Perdiodic execution
retry_period = get_retry_period(profile->http_retry_minimum_wait_interval);
profile->next_period = now + profile->reporting_interval;
profile->next_retry = now + retry_period;
profile->retry_count = 1;
profile->min_retry = profile->http_retry_minimum_wait_interval * 2;
if((profile->next_retry < profile->next_period) && profile->http_retry_enable) {
bulkdata_log(SINFO, "Retry session of profile_id %d in %d sec", profile->profile_id, retry_period);
uloop_timeout_set(timeout, 1000 * retry_period);
}
else {
bulkdata_log(SINFO, "Start New session of profile_id %d in %d sec", profile->profile_id, profile->reporting_interval);
uloop_timeout_set(timeout, 1000 * profile->reporting_interval);
}
} else { //Retry execution
retry_period= get_retry_period(profile->min_retry);
profile->min_retry*=2;
profile->next_retry+=retry_period;
profile->retry_count++;
if(profile->next_retry < profile->next_period) {
bulkdata_log(SINFO, "Retry session of profile_id %d in %d sec", profile->profile_id, retry_period);
uloop_timeout_set(timeout, 1000 * retry_period);
}
else {
bulkdata_log(SINFO, "Retry session of profile_id %d in %d sec", profile->profile_id, (profile->next_period-profile->next_retry+retry_period));
uloop_timeout_set(timeout, 1000 * (profile->next_period-profile->next_retry+retry_period));
}
}
if(profile->new_report){
bulkdata_add_failed_report(profile, profile->new_report);
FREE(profile->new_report);
}
FREE(report);
} else {
if(profile->retry_count == 0 || profile->next_retry > now || !profile->http_retry_enable) {
bulkdata_log(SINFO, "Start New session of profile_id %d in %d sec", profile->profile_id, profile->reporting_interval);
uloop_timeout_set(timeout, 1000 * profile->reporting_interval);
}
else {
bulkdata_log(SINFO, "Retry session of profile_id %d in %d sec", profile->profile_id, (profile->next_period-profile->next_retry));
uloop_timeout_set(timeout, 1000 * (profile->next_period-profile->next_retry));
}
FREE(profile->new_report);
FREE(report);
empty_failed_reports_list(profile);
profile->retry_count= 0;
}
}
int main(void)
{
struct bulkdata *bulkdata = &bulkdata_main;
if (bulkdata_config_init(bulkdata) == -1)
return -1;
bulkdata_log(SINFO, "Start bulkdatad daemon");
uloop_init();
bulkdata_run_profiles(bulkdata);
uloop_run();
uloop_done();
bulkdata_config_fini(bulkdata);
bulkdata_log(SINFO, "Stop bulkdatad daemon");
return 0;
}

18
bulkdata/src/bulkdata.h Normal file
View File

@@ -0,0 +1,18 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Copyright (C) 2020 iopsys Software Solutions AB
* Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
*
*/
#ifndef __BULKDATA_H
#define __BULKDATA_H
extern struct bulkdata bulkdata_main;
extern int profiles_number;
#endif /* __BULKDATA_H */

105
bulkdata/src/bulkdata.md Normal file
View File

@@ -0,0 +1,105 @@
# README #
bulkdatad is an implementation of The HTTP bulk data collection mechanism which is an extended feature of CPE and other agents implementing TR-069(CWMP) or TR-369(USP), defined by the Broadband Forum. It provides a means by which an Auto-Configuration Server (ACS), or USP Controller, can configure an agent to periodically send a JSON or CSV formatted set of Device information to an HTTP server running a data collection application.
## Configuration File ##
The bulkdatad UCI configuration is located in **'/etc/config/bulkdata'**, and contains 4 sections: **bulkdata**, **profile**, **profile\_parameter** and **profile\_http\_request\_uri\_parameter**.
```
config bulkdata 'bulkdata'
option enable '0'
option log_level '3'
config profile
option profile_id '1'
option enable '0'
option csv_encoding_row_time_stamp 'unix'
option json_encoding_report_time_stamp 'unix'
option http_retry_minimum_wait_interval '5'
option http_retry_interval_multiplier '2000'
config profile_parameter
option profile_id '1'
option name ''
option reference ''
config profile_http_request_uri_parameter
option profile_id '1'
option name ''
option reference ''
```
### bulkdata section ###
It defines **bulkdata configuration**: enable and log\_level.
| Name | Type | Description |
| ----------- | ------- | ----------------------------------------------------------------------------------------------- |
| `enable` | boolean | Enables the BulkData feature if set to **1**. |
| `log_level` | integer | Specifies the log type to use, by default **'INFO'**. The possible types are **'EMERG', 'ALERT', 'CRITIC' ,'ERROR', 'WARNING', 'NOTICE', 'INFO' and 'DEBUG'**. |
### profile section ###
It defines **the profile section configuration**: enable, name,... The possible options for **profile** section are listed below:
| Name | Type | Description |
| ---------------------------------- | ------- | ---------------------------------------------- |
| `profile_id` | integer | The profile id to use. |
| `enable` | boolean | If set to **1**, enables the bulkdata profile. |
| `name` | string | The name of the profile. |
| `nbre_of_retained_failed_reports` | integer | The number of failed reports to be retained and transmitted at the end of the current reporting interval. |
| `protocol` | string | The protocol used for the collection profile. |
| `encoding_type` | string | The encoding type used for the collection profile. |
| `reporting_interval` | integer | The reporting interval in seconds. |
| `time_reference` | integer | The time reference to determine when the profile will be transmitted to the ACS collector. |
| `csv_encoding_field_separator` | string | The field separator to use when encoding CSV data. |
| `csv_encoding_row_separator` | string | The row separator to use when encoding CSV data. |
| `csv_encoding_escape_character` | string | The escape character to use when encoding CSV data. |
| `csv_encoding_report_format` | string | Describes how reports will be formatted. Two possible formats are supported: **'ParameterPerRow' and 'ParameterPerColumn'**. |
| `csv_encoding_row_time_stamp` | string | The format of the timestamp to use for data inserted into the row. The row time stamp supported are **'Unix-Epoch', 'ISO-8601' and 'None'**. |
| `json_encoding_report_format` | string | Describes the report format. The supported report formats are **'ObjectHierarchy' and 'NameValuePair'**. |
| `json_encoding_report_time_stamp` | string | The format of the timestamp to use for the JSON Object named "CollectionTime". The supported timestamp are **'Unix-Epoch', 'ISO-8601' and 'None'**. |
| `http_url` | string | The URL of the collection server. |
| `http_username` | string | The username of the collection server. |
| `http_password` | string | The password of the collection server. |
| `http_compression` | string | The HTTP Compression mechanism used by the collection server. The supported compression mechanism are **'GZIP', 'Compress' and 'Deflate'**. |
| `http_method` | string | The HTTP method used by the collection server. Two methods are supported: **'POST' and 'PUT'**. |
| `http_use_date_header` | boolean | If set to **1**, the CPE encodes the HTTP Date Header. |
| `http_retry_enable` | boolean | If set to **1**, the CPE retries unsuccessful attempts to transfer data. |
| `http_retry_minimum_wait_interval` | integer | The data transfer retry wait interval. |
| `http_retry_interval_multiplier` | integer | The retry interval multiplier. |
| `http_persist_across_reboot` | boolean | If set to **1**, failed data transfers must be persisted across reboots. |
### profile_parameter section ###
It defines **the profile\_parameter section configuration**: profile\_id, name, reference.
| Name | Type | Description |
| ------------ | ------- | --------------------------------------- |
| `profile_id` | integer | The id of the used profile. |
| `name` | string | The name of the profile parameter. |
| `reference` | string | The reference of the profile parameter. |
### profile_http_request_uri_parameter section ###
It defines **the profile\_http\_request\_uri\_parameter section configuration**: profile\_id, name, reference.
| Name | Type | Description |
| ------------ | ------- | --------------------------------------- |
| `profile_id` | integer | The id of the used profile. |
| `name` | string | The name of the Request-URI parameter. |
| `reference` | string | The reference of the profile parameter. |
## Dependencies ##
To successfully build bulkdatad, the following libraries are needed:
| Dependency | Link | License |
| ----------- | ------------------------------------------- | -------------- |
| libuci | https://git.openwrt.org/project/uci.git | LGPL 2.1 |
| libubox | https://git.openwrt.org/project/libubox.git | BSD |
| libjson-c | https://s3.amazonaws.com/json-c_releases | MIT |
| libcurl | https://dl.uxnr.de/mirror/curl | MIT |
| libbbfdm | https://dev.iopsys.eu/iopsys/bbf.git | LGPL 2.1 |

450
bulkdata/src/common.c Normal file
View File

@@ -0,0 +1,450 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Copyright (C) 2020 iopsys Software Solutions AB
* Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
* Omar Kallel <omar.kallel@pivasoftware.com>
*/
#include "common.h"
static pathnode *head = NULL;
static pathnode *temphead = NULL;
int bulkdata_dm_ctx_init(struct dmctx *ctx)
{
struct bulkdata *bulkdata = &bulkdata_main;
dm_ctx_init(ctx, bulkdata->instance_mode);
return 0;
}
int bulkdata_dm_ctx_clean(struct dmctx *ctx)
{
dm_ctx_clean(ctx);
return 0;
}
static char **str_split(const char* str, const char* delim, size_t* numtokens)
{
char *s = strdup(str);
size_t tokens_alloc = 1;
size_t tokens_used = 0;
char **tokens = calloc(tokens_alloc, sizeof(char*));
char *token, *strtok_ctx;
for (token = strtok_r(s, delim, &strtok_ctx); token != NULL; token = strtok_r(NULL, delim, &strtok_ctx)) {
if (tokens_used == tokens_alloc) {
tokens_alloc *= 2;
tokens = realloc(tokens, tokens_alloc * sizeof(char*));
}
tokens[tokens_used++] = strdup(token);
}
// cleanup
if (tokens_used == 0) {
FREE(tokens);
} else {
tokens = realloc(tokens, tokens_used * sizeof(char*));
}
*numtokens = tokens_used;
FREE(s);
return tokens;
}
static bool bulkdata_match(const char *string, const char *pattern)
{
regex_t re;
if (regcomp(&re, pattern, REG_EXTENDED) != 0) return 0;
int status = regexec(&re, string, 0, NULL, 0);
regfree(&re);
if (status != 0) return false;
return true;
}
static bool is_res_required(char *str, int *start, int *len)
{
char temp_char[NAME_MAX] = {'\0'};
if (bulkdata_match(str, GLOB_CHAR)) {
int s_len = strlen(str);
int b_len = s_len, p_len = s_len;
char *star = strchr(str, '*');
if(star)
s_len = star - str;
*start = MIN(MIN(s_len, p_len), b_len);
if (*start == s_len)
*len = 1;
strncpy(temp_char, str+*start, *len);
if (bulkdata_match(temp_char, "[*+]+"))
return true;
}
*start = strlen(str);
return false;
}
static void insert(char *data, bool active)
{
pathnode *link = (pathnode*) calloc(1, sizeof(pathnode));
if(!link) {
return;
}
link->ref_path = data;
if(active) {
link->next = head;
head = link;
} else {
link->next = temphead;
temphead = link;
}
}
static void swap_heads(void)
{
pathnode *temp = head;
head = temphead;
temphead = temp;
}
static void deleteList(void)
{
pathnode *ptr = head, *temp;
while(ptr != NULL) {
temp = ptr;
free(ptr->ref_path);
if(ptr->next != NULL) {
ptr = ptr->next;
} else {
ptr = NULL;
}
free(temp);
}
head = NULL;
swap_heads();
}
void bulkdata_add_data_to_list(struct list_head *dup_list, char *name, char *value, char *type)
{
struct resultsnode *link;
link = calloc(1, sizeof(struct resultsnode));
list_add_tail(&link->list, dup_list);
link->name = strdup(name);
link->data = strdup(value);
link->type = strdup(type);
}
void bulkdata_delete_data_from_list(struct resultsnode *link)
{
list_del(&link->list);
FREE(link->name);
FREE(link->data);
FREE(link->type);
FREE(link);
}
void bulkdata_free_data_from_list(struct list_head *dup_list)
{
struct resultsnode *link;
while (dup_list->next != dup_list) {
link = list_entry(dup_list->next, struct resultsnode, list);
bulkdata_delete_data_from_list(link);
}
}
static bool bulkdata_get(int operation, char *path, struct dmctx *dm_ctx)
{
int fault = 0;
switch(operation) {
case CMD_GET_NAME:
fault = dm_entry_param_method(dm_ctx, CMD_GET_NAME, path, "true", NULL);
break;
case CMD_GET_VALUE:
fault = dm_entry_param_method(dm_ctx, CMD_GET_VALUE, path, NULL, NULL);
break;
default:
return false;
}
if (dm_ctx->list_fault_param.next != &dm_ctx->list_fault_param) {
return false;
}
if (fault) {
return false;
}
return true;
}
char *bulkdata_get_value_param(char *path)
{
struct dmctx ctx = {0};
struct dm_parameter *n;
char *value = NULL;
bulkdata_dm_ctx_init(&ctx);
if(bulkdata_get(CMD_GET_VALUE, path, &ctx)) {
list_for_each_entry(n, &ctx.list_parameter, list) {
value = strdup(n->data);
break;
}
}
bulkdata_dm_ctx_clean(&ctx);
return value;
}
void bulkdata_get_value(char *path, struct list_head *list)
{
struct dmctx ctx = {0};
struct dm_parameter *n;
bulkdata_dm_ctx_init(&ctx);
if(bulkdata_get(CMD_GET_VALUE, path, &ctx)) {
list_for_each_entry(n, &ctx.list_parameter, list) {
bulkdata_add_data_to_list(list, n->name, n->data, n->type);
}
}
bulkdata_dm_ctx_clean(&ctx);
}
bool bulkdata_get_name(char *path)
{
struct dmctx ctx = {0};
struct dm_parameter *n;
bool ret = false;
bulkdata_dm_ctx_init(&ctx);
if(bulkdata_get(CMD_GET_NAME, path, &ctx)) {
list_for_each_entry(n, &ctx.list_parameter, list) {
insert(strdup(n->name), false);
}
ret = true;
}
bulkdata_dm_ctx_clean(&ctx);
return ret;
}
static void fill_node_path(void)
{
pathnode *p=head;
while(p!=NULL) {
bulkdata_get_name(p->ref_path);
p=p->next;
}
deleteList();
}
static void bulkdata_filter_results(char *path, int start, int end)
{
int startpos = start, m_index = 0, m_len = 0;
char *pp = path + startpos;
char exp[NAME_MAX] = {'\0'};
if(start >= end) {
return;
}
if(!is_res_required(pp, &m_index, &m_len)) {
//append rest of the path to the final list
if(pp == path ) {
insert(strdup(pp), true);
return;
}
pathnode *p = head;
while(p != NULL) {
char name[NAME_MAX] = {'\0'};
strcpy(name, p->ref_path);
strcat(name, pp);
insert(strdup(name), false);
p = p->next;
}
deleteList();
return;
}
// Get the string before the match
char name[NAME_MAX]={'\0'};
strncpy(name, pp, m_index);
pathnode *p = head;
if(p == NULL) {
insert(strdup(name), false);
}
while(p != NULL) {
char ref_name[NAME_MAX] = {'\0'};
sprintf(ref_name, "%s%s", p->ref_path, name);
insert(strdup(ref_name), false);
p = p->next;
}
deleteList();
startpos += m_index;
strncpy(exp, pp+m_index, m_len);
pp = path + startpos;
fill_node_path();
startpos += 2;
bulkdata_filter_results(path, startpos, end);
}
static void bulkdata_parse_results(struct list_head *list)
{
pathnode *p = head;
while(p != NULL) {
bulkdata_get_value(p->ref_path, list);
p = p->next;
}
deleteList();
}
void bulkdata_get_value_results(char *path, struct list_head *list)
{
bulkdata_filter_results(path, 0, strlen(path));
bulkdata_parse_results(list);
}
char *create_request_url(struct profile *profile)
{
int i = 0, http_uri_number = profile->profile_http_request_uri_parameter_number;
char *value, *uri_param = NULL, *uri_tmp = NULL, *http_url = NULL;
for (i = 0; i < http_uri_number; i++)
{
if((profile->profile_http_uri_parameter[i].reference == NULL) || (profile->profile_http_uri_parameter[i].name == NULL))
continue;
value = bulkdata_get_value_param(profile->profile_http_uri_parameter[i].reference);
if(!uri_param) {
asprintf(&uri_param, "&%s=%s", profile->profile_http_uri_parameter[i].name, value);
free(value);
}
else {
uri_tmp = strdup(uri_param);
free(uri_param);
asprintf(&uri_param, "%s&%s=%s", uri_tmp, profile->profile_http_uri_parameter[i].name, value);
free(value);
free(uri_tmp);
}
}
if(uri_param) {
asprintf(&http_url, "%s%s", profile->http_url, uri_param);
free(uri_param);
} else {
asprintf(&http_url, "%s", profile->http_url);
}
return http_url;
}
char *get_bulkdata_profile_parameter_name(char *paramref, char *paramname, char *param)
{
char **paramarr, *idx1 = NULL, *idx2 = NULL, *res = NULL, *instance = NULL, *tmp = NULL, *retparam = NULL, *s = NULL;
int i, j = 0;
size_t length;
if(paramname == NULL || strlen(paramname) <= 0)
return strdup(param);
paramarr = str_split(paramref, "*", &length);
res = strdup(paramname);
for(i = 0; i < length; i++) {
if(i == length - 1)
break;
j++;
idx1 = strstr(param, paramarr[i]);
idx2 = strstr(param, paramarr[i+1]);
instance = (char*)calloc(idx2 - idx1 - strlen(paramarr[i]) + 1, sizeof(char));
memcpy(instance, idx1 + strlen(paramarr[i]), idx2 - idx1 - strlen(paramarr[i]));
tmp = strdup(res);
FREE(res);
asprintf(&res, "%s.%s", tmp, instance);
FREE(tmp);
FREE(instance);
}
if ((s = strstr(param,paramarr[j]) ) != NULL && strlen(s) == strlen(paramarr[j]))
asprintf(&retparam, "%s", res);
else
asprintf(&retparam, "%s.%s", res, strstr(param, paramarr[j]) + strlen(paramarr[j]));
FREE(res);
for(int k = 0; k < length; k++)
FREE(paramarr[k]);
FREE(paramarr);
return retparam;
}
void append_string_to_string(char *strappend, char **target)
{
char *tmp = NULL;
if(strappend == NULL || strlen(strappend) <= 0)
return;
if(*target == NULL || strlen(*target) <= 0) {
*target = strdup(strappend);
return;
} else {
tmp = strdup(*target);
FREE(*target);
}
asprintf(target, "%s%s", tmp, strappend);
FREE(tmp);
}
void bulkdata_add_failed_report(struct profile *profile, char *freport)
{
struct failed_reports *report, *retreport, *rtmp;
if(profile->nbre_failed_reports < profile->nbre_of_retained_failed_reports || profile->nbre_of_retained_failed_reports < 0) {
profile->nbre_failed_reports++;
} else {
list_for_each_entry_safe(retreport, rtmp, profile->failed_reports, list) {
bulkdata_delete_failed_report(retreport);
break;
}
}
report = calloc(1, sizeof(struct failed_reports));
list_add_tail(&report->list, profile->failed_reports);
report->freport= strdup(freport);
}
void bulkdata_delete_failed_report(struct failed_reports *report)
{
if(report != NULL) {
list_del(&report->list);
FREE(report->freport);
FREE(report);
}
}
struct failed_reports* empty_failed_reports_list(struct profile *profile)
{
struct failed_reports *report, *rtmp;
if(list_empty(profile->failed_reports))
return NULL;
list_for_each_entry_safe(report, rtmp, profile->failed_reports, list) {
list_del(&report->list);
FREE(report->freport);
FREE(report);
}
return NULL;
}
void add_failed_reports_to_report_csv(struct profile *profile, char **report, int isnext)
{
struct failed_reports *retreport = NULL;
int j = 0;
if(list_empty(profile->failed_reports))
return;
list_for_each_entry(retreport, profile->failed_reports, list) {
if(!j && isnext) {
j = 1;
continue;
}
append_string_to_string(retreport->freport, report);
}
}

69
bulkdata/src/common.h Normal file
View File

@@ -0,0 +1,69 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Copyright (C) 2020 iopsys Software Solutions AB
* Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
*
*/
#ifndef __COMMON_H
#define __COMMON_H
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <regex.h>
#include <sys/param.h>
#include <libubox/blobmsg.h>
#include <libubox/blobmsg_json.h>
#include <libubox/utils.h>
#include <libubus.h>
#include <libbbfdm/dmentry.h>
#include <libbbfdm/dmbbfcommon.h>
#include "config.h"
#include "log.h"
#include "bulkdata.h"
typedef struct pathnode {
char *ref_path;
struct pathnode *next;
} pathnode;
typedef struct resultsnode {
struct list_head list;
char *name;
char *data;
char *type;
} resultsnode;
struct failed_reports {
struct list_head list;
char *freport;
};
#define GLOB_CHAR "[[+*]+"
int bulkdata_dm_ctx_init(struct dmctx *ctx);
int bulkdata_dm_ctx_clean(struct dmctx *ctx);
char *bulkdata_get_value_param(char *path);
void bulkdata_get_value(char *path, struct list_head *list);
void bulkdata_free_data_from_list(struct list_head *dup_list);
void bulkdata_get_value_results(char *path, struct list_head *list);
char *create_request_url(struct profile *profile);
char *get_bulkdata_profile_parameter_name(char *paramref, char *paramname, char *param);
void append_string_to_string(char *strappend, char **target);
void bulkdata_add_failed_report(struct profile *profile, char *freport);
void bulkdata_delete_failed_report(struct failed_reports *report);
struct failed_reports *empty_failed_reports_list(struct profile *profile);
void add_failed_reports_to_report_csv(struct profile *profile, char **report, int isnext);
#endif //__COMMON_H

523
bulkdata/src/config.c Normal file
View File

@@ -0,0 +1,523 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Copyright (C) 2020 iopsys Software Solutions AB
* Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
* Omar Kallel <omar.kallel@pivasoftware.com>
*/
#include <stdio.h>
#include <strings.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include "log.h"
#include "config.h"
#include "buci.h"
#include "common.h"
#include "bulkdata.h"
int get_log_level_config(struct bulkdata *bulkdata)
{
char *value = NULL;
buci_init();
value = buci_get_value("bulkdata", "bulkdata", "log_level");
if(value != NULL && *value != '\0')
bulkdata->log_level = atoi(value);
else
bulkdata->log_level = DEFAULT_LOGLEVEL;
bulkdata_log(SDEBUG,"Log Level of Bulkdata is : %d", bulkdata->log_level);
buci_fini();
return 0;
}
int get_amd_version_config(struct bulkdata *bulkdata)
{
char *value = NULL;
buci_init();
value = buci_get_value("cwmp", "cpe", "amd_version");
if(value != NULL && *value != '\0')
bulkdata->amd_version = atoi(value);
else
bulkdata->amd_version = DEFAULT_AMD_VERSION;
bulkdata_log(SDEBUG,"CWMP Amendment Version is : %d", bulkdata->amd_version);
buci_fini();
return 0;
}
int get_instance_mode_config(struct bulkdata *bulkdata)
{
char *value = NULL;
buci_init();
value = buci_get_value("cwmp", "cpe", "instance_mode");
if(value != NULL && *value != '\0') {
if(!strcmp(value, "InstanceNumber"))
bulkdata->instance_mode = INSTANCE_MODE_NUMBER;
else
bulkdata->instance_mode = INSTANCE_MODE_ALIAS;
}
else
bulkdata->instance_mode = DEFAULT_INSTANCE_MODE;
bulkdata_log(SDEBUG,"CWMP Instance Mode is : %d", bulkdata->instance_mode);
buci_fini();
return 0;
}
int get_device_id_config(struct bulkdata *bulkdata)
{
struct dmctx dmctx = {0};
bulkdata_dm_ctx_init(&dmctx);
bulkdata->device_id.manufacturer_oui = bulkdata_get_value_param("Device.DeviceInfo.ManufacturerOUI");
bulkdata->device_id.product_class = bulkdata_get_value_param("Device.DeviceInfo.ProductClass");
bulkdata->device_id.serial_number = bulkdata_get_value_param("Device.DeviceInfo.SerialNumber");
bulkdata_dm_ctx_clean(&dmctx);
return 0;
}
int load_profile_config(struct bulkdata *bulkdata, struct uci_section *s, int i)
{
char *value = NULL;
value = buci_get_value_bysection(s, "profile_id");
if(value != NULL && *value != '\0') {
bulkdata->profile[i].profile_id = atoi(value);
value = NULL;
bulkdata_log(SDEBUG,"The profile_id of profile_id %d is : %d", i, bulkdata->profile[i].profile_id);
} else
return -1;
value = buci_get_value_bysection(s, "nbre_of_retained_failed_reports");
if(value != NULL && *value != '\0') {
bulkdata->profile[i].nbre_of_retained_failed_reports = atoi(value);
value = NULL;
bulkdata_log(SDEBUG,"The nombre of retained failed reports of profile_id %d is : %d", bulkdata->profile[i].profile_id, bulkdata->profile[i].nbre_of_retained_failed_reports);
}
value = buci_get_value_bysection(s, "protocol");
if(value != NULL && *value != '\0' && strcasecmp(value, "http")==0) {
bulkdata->profile[i].protocol = strdup(value);
value = NULL;
bulkdata_log(SDEBUG,"The protocol of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].protocol);
} else
return -1;
value = buci_get_value_bysection(s, "encoding_type");
if(value != NULL && *value != '\0') {
bulkdata->profile[i].encoding_type = strdup(value);
value = NULL;
bulkdata_log(SDEBUG,"The encoding type of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].encoding_type);
} else
return -1;
value = buci_get_value_bysection(s, "reporting_interval");
if(value != NULL && *value != '\0') {
bulkdata->profile[i].reporting_interval = atoi(value);
value = NULL;
bulkdata_log(SDEBUG,"The reporting interval of profile_id %d is : %d", bulkdata->profile[i].profile_id, bulkdata->profile[i].reporting_interval);
} else
return -1;
value = buci_get_value_bysection(s, "time_reference");
if(value != NULL && *value != '\0') {
bulkdata->profile[i].time_reference = atoi(value);
value = NULL;
bulkdata_log(SDEBUG,"The time reference of profile_id %d is : %ld", bulkdata->profile[i].profile_id, bulkdata->profile[i].time_reference);
} else
return -1;
value = buci_get_value_bysection(s, "csv_encoding_field_separator");
if(value != NULL && *value != '\0') {
bulkdata->profile[i].csv_encoding_field_separator = strdup(value);
value = NULL;
bulkdata_log(SDEBUG,"The csv encoding field separator of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].csv_encoding_field_separator);
} else
return -1;
value = buci_get_value_bysection(s, "csv_encoding_row_separator");
if(value != NULL && *value != '\0') {
bulkdata->profile[i].csv_encoding_row_separator = strdup(value);
value = NULL;
bulkdata_log(SDEBUG,"The csv encoding row separator of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].csv_encoding_row_separator);
} else
return -1;
value = buci_get_value_bysection(s, "csv_encoding_escape_character");
if(value != NULL && *value != '\0') {
bulkdata->profile[i].csv_encoding_escape_character = strdup(value);
value = NULL;
bulkdata_log(SDEBUG,"The csv encoding escape character of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].csv_encoding_escape_character);
}
value = buci_get_value_bysection(s, "csv_encoding_report_format");
if(value != NULL && *value != '\0') {
bulkdata->profile[i].csv_encoding_report_format = strdup(value);
value = NULL;
bulkdata_log(SDEBUG,"The csv encoding report format of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].csv_encoding_report_format);
} else
return -1;
value = buci_get_value_bysection(s, "csv_encoding_row_time_stamp");
if(value != NULL && *value != '\0') {
bulkdata->profile[i].csv_encoding_row_time_stamp = strdup(value);
value = NULL;
bulkdata_log(SDEBUG,"The csv encoding row time stamp of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].csv_encoding_row_time_stamp);
} else
return -1;
value = buci_get_value_bysection(s, "json_encoding_report_format");
if(value != NULL && *value != '\0') {
bulkdata->profile[i].json_encoding_report_format = strdup(value);
value = NULL;
bulkdata_log(SDEBUG,"The json encoding report format of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].json_encoding_report_format);
} else
return -1;
value = buci_get_value_bysection(s, "json_encoding_report_time_stamp");
if(value != NULL && *value != '\0') {
bulkdata->profile[i].json_encoding_report_time_stamp = strdup(value);
value = NULL;
bulkdata_log(SDEBUG,"The json encoding report time stamp of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].json_encoding_report_time_stamp);
} else
return -1;
value = buci_get_value_bysection(s, "http_url");
if(value != NULL && *value != '\0') {
char *url = NULL;
asprintf(&url, "%s?oui=%s&pc=%s&sn=%s", value, bulkdata->device_id.manufacturer_oui, bulkdata->device_id.serial_number, bulkdata->device_id.serial_number);
bulkdata->profile[i].http_url = strdup(url);
free(url);
value = NULL;
bulkdata_log(SDEBUG,"The HTTP url of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].http_url);
} else
return -1;
value = buci_get_value_bysection(s, "http_username");
if(value != NULL && *value != '\0') {
bulkdata->profile[i].http_username = strdup(value);
value = NULL;
bulkdata_log(SDEBUG,"The HTTP username of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].http_username);
} else {
bulkdata->profile[i].http_username = NULL;
}
value = buci_get_value_bysection(s, "http_password");
if(value != NULL && *value != '\0') {
bulkdata->profile[i].http_password = strdup(value);
value = NULL;
bulkdata_log(SDEBUG,"The HTTP password of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].http_password);
} else {
bulkdata->profile[i].http_password = NULL;
}
value = buci_get_value_bysection(s, "http_compression");
if(value != NULL && *value != '\0') {
bulkdata->profile[i].http_compression = strdup(value);
value = NULL;
bulkdata_log(SDEBUG,"The HTTP compression of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].http_compression);
} else
return -1;
value = buci_get_value_bysection(s, "http_method");
if(value != NULL && *value != '\0') {
bulkdata->profile[i].http_method = strdup(value);
value = NULL;
bulkdata_log(SDEBUG,"The HTTP method of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].http_method);
} else
return -1;
value = buci_get_value_bysection(s, "http_use_date_header");
if(value != NULL && *value != '\0') {
bulkdata->profile[i].http_use_date_header = atoi(value);
value = NULL;
bulkdata_log(SDEBUG,"The HTTP use date header of profile_id %d is : %d", bulkdata->profile[i].profile_id, bulkdata->profile[i].http_use_date_header);
}
value = buci_get_value_bysection(s, "http_retry_enable");
if(value != NULL && *value != '\0') {
bulkdata->profile[i].http_retry_enable = atoi(value);
value = NULL;
bulkdata_log(SDEBUG,"The HTTP retry enable of profile_id %d is : %d", bulkdata->profile[i].profile_id, bulkdata->profile[i].http_retry_enable);
} else
return -1;
value = buci_get_value_bysection(s, "http_retry_minimum_wait_interval");
if(value != NULL && *value != '\0') {
bulkdata->profile[i].http_retry_minimum_wait_interval = atoi(value);
value = NULL;
bulkdata_log(SDEBUG,"The HTTP retry minimum wait interval of profile_id %d is : %d", bulkdata->profile[i].profile_id, bulkdata->profile[i].http_retry_minimum_wait_interval);
}
value = buci_get_value_bysection(s, "http_retry_interval_multiplier");
if(value != NULL && *value != '\0') {
bulkdata->profile[i].http_retry_interval_multiplier = atoi(value);
value = NULL;
bulkdata_log(SDEBUG,"The HTTP retry interval multiplier of profile_id %d is : %d", bulkdata->profile[i].profile_id, bulkdata->profile[i].http_retry_interval_multiplier);
}
value = buci_get_value_bysection(s, "http_persist_across_reboot");
if(value != NULL && *value != '\0') {
bulkdata->profile[i].http_persist_across_reboot = atoi(value);
value = NULL;
bulkdata_log(SDEBUG,"The HTTP persist across reboot of profile_id %d is : %d", bulkdata->profile[i].profile_id, bulkdata->profile[i].http_persist_across_reboot);
} else
return -1;
value = buci_get_value_bysection(s, "http_ssl_capath");
if(value != NULL && *value != '\0') {
bulkdata->profile[i].http_ssl_capath = strdup(value);
value = NULL;
bulkdata_log(SDEBUG,"The HTTP ssl capath of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].http_ssl_capath);
} else {
bulkdata->profile[i].http_ssl_capath = NULL;
}
value = buci_get_value_bysection(s, "http_insecure_enable");
if(value != NULL && *value != '\0') {
bulkdata->profile[i].http_insecure_enable = atoi(value);
value = NULL;
bulkdata_log(SDEBUG,"The HTTP insecure enable of profile_id %d is : %d", bulkdata->profile[i].profile_id, bulkdata->profile[i].http_insecure_enable);
}
bulkdata->profile[i].retry_count = 0;
bulkdata->profile[i].nbre_failed_reports = 0;
return 0;
}
int get_profiles_enable(struct bulkdata *bulkdata)
{
struct uci_section *s;
char *enable;
int i = 0, nbr_profiles = 0;
buci_init();
buci_foreach_section("bulkdata", "profile", s) {
enable = buci_get_value_bysection(s, "enable");
if(strcmp(enable, "1") == 0) {
nbr_profiles++;
}
}
if(nbr_profiles != 0)
bulkdata->profile = calloc(2, sizeof(struct profile));
buci_foreach_section("bulkdata", "profile", s) {
enable = buci_get_value_bysection(s, "enable");
if(strcmp(enable, "1") == 0) {
if(load_profile_config(bulkdata, s, i) == -1) {
bulkdata_log(SCRIT,"Not able to start bulkdata: some required bulkdata configurations in profile must be set");
return -1;
}
i++;
}
}
profiles_number = nbr_profiles;
buci_fini();
return 0;
}
int load_profile_parameter_config(struct bulkdata *bulkdata, struct uci_section *s, int i, int j)
{
char *value = NULL;
value = buci_get_value_bysection(s, "name");
if(value != NULL && *value != '\0') {
bulkdata->profile[i].profile_parameter[j].name = strdup(value);
value = NULL;
bulkdata_log(SDEBUG,"The parameter name %d of profile_id %d is : %s", j+1, bulkdata->profile[i].profile_id, bulkdata->profile[i].profile_parameter[j].name);
} else {
bulkdata->profile[i].profile_parameter[j].name = NULL;
}
value = buci_get_value_bysection(s, "reference");
if(value != NULL && *value != '\0') {
bulkdata->profile[i].profile_parameter[j].reference = strdup(value);
value = NULL;
bulkdata_log(SDEBUG,"The parameter reference %d of profile_id %d is : %s", j+1, bulkdata->profile[i].profile_id, bulkdata->profile[i].profile_parameter[j].reference);
} else
return -1;
return 0;
}
int get_profiles_parameters(struct bulkdata *bulkdata)
{
struct uci_section *s;
char *profile_id;
int i, j, nbr_profile_parameters;
buci_init();
for (i = 0; i < profiles_number; i++) {
j = 0;
nbr_profile_parameters = 0;
buci_foreach_section("bulkdata", "profile_parameter", s) {
profile_id = buci_get_value_bysection(s, "profile_id");
if(bulkdata->profile[i].profile_id != atoi(profile_id))
continue;
nbr_profile_parameters++;
if(nbr_profile_parameters == 1) {
bulkdata->profile[i].profile_parameter = calloc(1, sizeof(struct profile_parameter));
} else {
bulkdata->profile[i].profile_parameter = realloc(bulkdata->profile[i].profile_parameter, nbr_profile_parameters * sizeof(struct profile_parameter));
}
if(load_profile_parameter_config(bulkdata, s, i, j) == -1) {
bulkdata_log(SCRIT,"Not able to start bulkdata: some required bulkdata configurations in profile_parameter must be set");
return -1;
}
j++;
}
bulkdata->profile[i].profile_parameter_number = nbr_profile_parameters;
}
buci_fini();
return 0;
}
int load_profile_http_request_uri_parameter_config(struct bulkdata *bulkdata, struct uci_section *s, int i, int j)
{
char *value = NULL;
value = buci_get_value_bysection(s, "name");
if(value != NULL && *value != '\0') {
bulkdata->profile[i].profile_http_uri_parameter[j].name = strdup(value);
value = NULL;
bulkdata_log(SDEBUG,"The HTTP resuest URI parameter name %d of profile_id %d is : %s", j+1, bulkdata->profile[i].profile_id, bulkdata->profile[i].profile_http_uri_parameter[j].name);
} else
return -1;
value = buci_get_value_bysection(s, "reference");
if(value != NULL && *value != '\0') {
bulkdata->profile[i].profile_http_uri_parameter[j].reference = strdup(value);
value = NULL;
bulkdata_log(SDEBUG,"The HTTP resuest URI parameter reference %d of profile_id %d is : %s", j+1, bulkdata->profile[i].profile_id, bulkdata->profile[i].profile_http_uri_parameter[j].reference);
} else
return -1;
return 0;
}
int get_profile_http_request_uri_parameter(struct bulkdata *bulkdata)
{
struct uci_section *s;
char *profile_id;
int i, j, nbr_profile_http_request_uri_parameter;
buci_init();
for (i = 0; i < profiles_number; i++) {
j = 0;
nbr_profile_http_request_uri_parameter = 0;
buci_foreach_section("bulkdata", "profile_http_request_uri_parameter", s) {
profile_id = buci_get_value_bysection(s, "profile_id");
if(bulkdata->profile[i].profile_id != atoi(profile_id))
continue;
nbr_profile_http_request_uri_parameter++;
if(nbr_profile_http_request_uri_parameter == 1) {
bulkdata->profile[i].profile_http_uri_parameter = calloc(1, sizeof(struct profile_http_request_uri_parameter));
} else {
bulkdata->profile[i].profile_http_uri_parameter = realloc(bulkdata->profile[i].profile_http_uri_parameter, nbr_profile_http_request_uri_parameter * sizeof(struct profile_http_request_uri_parameter));
}
if(load_profile_http_request_uri_parameter_config(bulkdata, s, i, j)== -1) {
bulkdata_log(SCRIT,"Not able to start bulkdata: some required bulkdata configurations in profile_http_request_uri_parameter must be set");
return -1;
}
j++;
}
bulkdata->profile[i].profile_http_request_uri_parameter_number = nbr_profile_http_request_uri_parameter;
}
buci_fini();
return 0;
}
int bulkdata_config_init(struct bulkdata *bulkdata)
{
get_log_level_config(bulkdata);
get_amd_version_config(bulkdata);
get_instance_mode_config(bulkdata);
get_device_id_config(bulkdata);
if (get_profiles_enable(bulkdata) == -1)
return -1;
if (get_profiles_parameters(bulkdata) == -1)
return -1;
if (get_profile_http_request_uri_parameter(bulkdata) == -1)
return -1;
return 0;
}
int free_device_id_config(struct bulkdata *bulkdata)
{
FREE(bulkdata->device_id.manufacturer_oui);
FREE(bulkdata->device_id.product_class);
FREE(bulkdata->device_id.serial_number);
return 0;
}
int free_profiles_enable(struct bulkdata *bulkdata)
{
for(int i = 0; i < profiles_number; i++) {
FREE(bulkdata->profile[i].protocol);
FREE(bulkdata->profile[i].encoding_type);
FREE(bulkdata->profile[i].csv_encoding_field_separator);
FREE(bulkdata->profile[i].csv_encoding_row_separator);
FREE(bulkdata->profile[i].csv_encoding_escape_character);
FREE(bulkdata->profile[i].csv_encoding_report_format);
FREE(bulkdata->profile[i].csv_encoding_row_time_stamp);
FREE(bulkdata->profile[i].json_encoding_report_format);
FREE(bulkdata->profile[i].json_encoding_report_time_stamp);
FREE(bulkdata->profile[i].http_url);
FREE(bulkdata->profile[i].http_username);
FREE(bulkdata->profile[i].http_password);
FREE(bulkdata->profile[i].http_compression);
FREE(bulkdata->profile[i].http_method);
FREE(bulkdata->profile[i].http_ssl_capath);
}
FREE(bulkdata->profile);
return 0;
}
int free_profiles_parameters(struct bulkdata *bulkdata)
{
for(int i = 0; i < profiles_number; i++) {
for(int j = 0; j < bulkdata->profile[i].profile_parameter_number; j++) {
FREE(bulkdata->profile[i].profile_parameter[j].name);
FREE(bulkdata->profile[i].profile_parameter[j].reference);
}
FREE(bulkdata->profile[i].profile_parameter);
}
return 0;
}
int free_profile_http_request_uri_parameter(struct bulkdata *bulkdata)
{
for(int i = 0; i < profiles_number; i++) {
for(int j = 0; j < bulkdata->profile[i].profile_http_request_uri_parameter_number; j++) {
FREE(bulkdata->profile[i].profile_http_uri_parameter[j].name);
FREE(bulkdata->profile[i].profile_http_uri_parameter[j].reference);
}
FREE(bulkdata->profile[i].profile_http_uri_parameter);
}
return 0;
}
int bulkdata_config_fini(struct bulkdata *bulkdata)
{
free_device_id_config(bulkdata);
free_profiles_parameters(bulkdata);
free_profile_http_request_uri_parameter(bulkdata);
free_profiles_enable(bulkdata);
return 0;
}

103
bulkdata/src/config.h Normal file
View File

@@ -0,0 +1,103 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Copyright (C) 2020 iopsys Software Solutions AB
* Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
*
*/
#ifndef __CONFIG_H
#define __CONFIG_H
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>
#include <libubox/uloop.h>
#define DEFAULT_AMD_VERSION 2
#define DEFAULT_INSTANCE_MODE 0
typedef struct device_id {
char *manufacturer_oui;
char *product_class;
char *serial_number;
} device_id;
typedef struct profile_parameter {
int profile_id;
char *name;
char *reference;
} profile_parameter;
typedef struct profile_http_request_uri_parameter {
int profile_id;
char *name;
char *reference;
} profile_http_request_uri_parameter;
typedef struct profile {
struct uloop_timeout utimer;
int profile_id;
int nbre_of_retained_failed_reports;
int nbre_failed_reports;
int reporting_interval;
int profile_parameter_number;
int profile_http_request_uri_parameter_number;
int http_retry_minimum_wait_interval;
int http_retry_interval_multiplier;
int min_retry;
int retry_count;
char *protocol;
char *encoding_type;
char *csv_encoding_field_separator;
char *csv_encoding_row_separator;
char *csv_encoding_escape_character;
char *csv_encoding_report_format;
char *csv_encoding_row_time_stamp;
char *json_encoding_report_format;
char *json_encoding_report_time_stamp;
char *http_url;
char *http_username;
char *http_password;
char *http_compression;
char *http_method;
char *http_ssl_capath;
char *new_report;
time_t time_reference;
time_t next_retry;
time_t next_period;
bool http_persist_across_reboot;
bool http_insecure_enable;
bool enable;
bool http_use_date_header;
bool http_retry_enable;
struct profile_parameter *profile_parameter;
struct profile_http_request_uri_parameter *profile_http_uri_parameter;
struct list_head *failed_reports;
} profile;
typedef struct bulkdata {
struct device_id device_id;
struct profile *profile;
int log_level;
int amd_version;
unsigned int instance_mode;
} bulkdata;
int bulkdata_config_init(struct bulkdata *bulkdata);
int bulkdata_config_fini(struct bulkdata *bulkdata);
#ifndef FREE
#define FREE(x) do { if(x) {free(x); x = NULL;} } while (0)
#endif
#endif //__CONFIG_H

1293
bulkdata/src/datamodel.c Normal file

File diff suppressed because it is too large Load Diff

29
bulkdata/src/datamodel.h Normal file
View File

@@ -0,0 +1,29 @@
/*
* Copyright (C) 2020 iopsys Software Solutions AB
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation
*
* Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
*/
#ifndef _BULKDATA_H_
#define _BULKDATA_H_
#include <libbbf_api/dmcommon.h>
extern DMOBJ tDeviceBulkDataObj[];
extern DMOBJ tBulkDataObj[];
extern DMLEAF tBulkDataParams[];
extern DMOBJ tBulkDataProfileObj[];
extern DMLEAF tBulkDataProfileParams[];
extern DMLEAF tBulkDataProfileParameterParams[];
extern DMLEAF tBulkDataProfileCSVEncodingParams[];
extern DMLEAF tBulkDataProfileJSONEncodingParams[];
extern DMOBJ tBulkDataProfileHTTPObj[];
extern DMLEAF tBulkDataProfileHTTPParams[];
extern DMLEAF tBulkDataProfileHTTPRequestURIParameterParams[];
#endif //__BULKDATA_H_

196
bulkdata/src/http.c Normal file
View File

@@ -0,0 +1,196 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Copyright (C) 2020 iopsys Software Solutions AB
* Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
* Omar Kallel <omar.kallel@pivasoftware.com>
*/
#include "http.h"
static struct http_client http_c;
static CURL *curl;
int http_client_init(struct profile *profile)
{
char *url = create_request_url(profile);
if(url) {
asprintf(&http_c.url, "%s", url);
free(url);
}
bulkdata_log(SINFO, "ACS url: %s", http_c.url);
curl_global_init(CURL_GLOBAL_SSL);
curl = curl_easy_init();
if (!curl) return -1;
return 0;
}
void http_client_exit(void)
{
FREE(http_c.url);
if (http_c.header_list) {
curl_slist_free_all(http_c.header_list);
http_c.header_list = NULL;
}
curl_easy_cleanup(curl);
curl_global_cleanup();
}
static size_t http_get_response(void *buffer, size_t size, size_t rxed, char **msg_in)
{
char *c;
if (asprintf(&c, "%s%.*s", *msg_in, (int) (size * rxed), (char *)buffer) == -1) {
FREE(*msg_in);
return -1;
}
free(*msg_in);
*msg_in = c;
return size * rxed;
}
int http_send_message(struct profile *profile, char *msg_out, int msg_out_len, char **msg_in)
{
CURLcode res;
long http_code = 0;
char errbuf[CURL_ERROR_SIZE];
http_c.header_list = NULL;
http_c.header_list = curl_slist_append(http_c.header_list, "User-Agent: iopsys-bulkdata");
if (!http_c.header_list) return -1;
if (profile->http_use_date_header) {
if (bulkdata_get_time() != NULL) {
http_c.header_list = curl_slist_append(http_c.header_list, bulkdata_get_time());
if (!http_c.header_list) return -1;
}
}
if (strcmp(profile->encoding_type, "json") == 0) {
http_c.header_list = curl_slist_append(http_c.header_list, "Content-Type: application/json; charset=\"utf-8\"");
if (!http_c.header_list) return -1;
if(strcmp (profile->json_encoding_report_format, "objecthierarchy") == 0) {
http_c.header_list = curl_slist_append(http_c.header_list, "BBF-Report-Format: \"ObjectHierarchy\"");
if (!http_c.header_list) return -1;
} else if(strcmp(profile->json_encoding_report_format, "namevaluepair") == 0) {
http_c.header_list = curl_slist_append(http_c.header_list, "BBF-Report-Format: \"NameValuePair\"");
if (!http_c.header_list) return -1;
}
} else if(strcmp(profile->encoding_type, "csv") == 0) {
http_c.header_list = curl_slist_append(http_c.header_list, "Content-Type: text/csv; charset=\"utf-8\"");
if (!http_c.header_list) return -1;
if(strcmp (profile->csv_encoding_report_format, "row") == 0) {
http_c.header_list = curl_slist_append(http_c.header_list, "BBF-Report-Format: \"ParameterPerRow\"");
if (!http_c.header_list) return -1;
} else if(strcmp (profile->csv_encoding_report_format, "column") == 0) {
http_c.header_list = curl_slist_append(http_c.header_list, "BBF-Report-Format: \"ParameterPerColumn\"");
if (!http_c.header_list) return -1;
}
}
curl_easy_setopt(curl, CURLOPT_URL, http_c.url);
curl_easy_setopt(curl, CURLOPT_USERNAME, profile->http_username);
curl_easy_setopt(curl, CURLOPT_PASSWORD, profile->http_password);
curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC|CURLAUTH_DIGEST);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, HTTP_TIMEOUT);
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, HTTP_TIMEOUT);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL);
curl_easy_setopt(curl, CURLOPT_NOBODY, 0);
if(strcasecmp(profile->http_compression, "gzip") == 0) {
curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "gzip");
http_c.header_list = curl_slist_append(http_c.header_list, "Content-Encoding: gzip");
} else if(strcasecmp(profile->http_compression, "compress") == 0) {
curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "compress");
http_c.header_list = curl_slist_append(http_c.header_list, "Content-Encoding: compress");
} else if(strcasecmp(profile->http_compression, "deflate") == 0) {
curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "deflate");
http_c.header_list = curl_slist_append(http_c.header_list, "Content-Encoding: deflate");
}
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, http_c.header_list);
if(strcasecmp(profile->http_method, "put") == 0)
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, msg_out);
if (msg_out)
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long) msg_out_len);
else
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, 0);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, http_get_response);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, msg_in);
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf);
if (profile->http_ssl_capath)
curl_easy_setopt(curl, CURLOPT_CAPATH, profile->http_ssl_capath);
if (profile->http_insecure_enable) {
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
}
*msg_in = (char *) calloc (1, sizeof(char));
res = curl_easy_perform(curl);
if(res != CURLE_OK) {
size_t len = strlen(errbuf);
if(len) {
if (errbuf[len - 1] == '\n') errbuf[len - 1] = '\0';
bulkdata_log(SCRIT, "libcurl: (%d) %s", res, errbuf);
} else {
bulkdata_log(SCRIT, "libcurl: (%d) %s", res, curl_easy_strerror(res));
}
}
if (!strlen(*msg_in))
FREE(*msg_in);
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
if(http_code == 200)
bulkdata_log(SINFO, "Receive HTTP 200 OK from Bulkdata Collector");
else if(http_code == 401)
bulkdata_log(SINFO, "Receive HTTP 401 Unauthorized from Bulkdata Collector");
else if(http_code == 204)
bulkdata_log(SINFO, "Receive HTTP 204 No Content from Bulkdata Collector");
else
bulkdata_log(SINFO, "Receive HTTP %d from Bulkdata Collector", http_code);
if(http_code == 415)
{
strcpy(profile->http_compression, "None");
goto error;
}
if (http_code != 200 && http_code != 204)
goto error;
curl_easy_reset(curl);
if (http_c.header_list) {
curl_slist_free_all(http_c.header_list);
http_c.header_list = NULL;
}
if (res) goto error;
return http_code;
error:
FREE(*msg_in);
if (http_c.header_list) {
curl_slist_free_all(http_c.header_list);
http_c.header_list = NULL;
}
return -1;
}

37
bulkdata/src/http.h Normal file
View File

@@ -0,0 +1,37 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Copyright (C) 2020 iopsys Software Solutions AB
* Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
*
*/
#ifndef __HTTP_H
#define __HTTP_H
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <curl/curl.h>
#include "config.h"
#include "log.h"
#include "times.h"
#include "common.h"
#define HTTP_TIMEOUT 30
struct http_client
{
struct curl_slist *header_list;
char *url;
};
int http_client_init(struct profile *profile);
void http_client_exit(void);
int http_send_message(struct profile *profile, char *msg_out, int msg_out_len, char **msg_in);
#endif //__HTTP_H

57
bulkdata/src/log.c Normal file
View File

@@ -0,0 +1,57 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Copyright (C) 2020 iopsys Software Solutions AB
* Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
*
*/
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <syslog.h>
#include <time.h>
#include "bulkdata.h"
#include "config.h"
#include "log.h"
static const int log_syslogmap[] = {
[SCRIT] = LOG_CRIT,
[SWARNING] = LOG_WARNING,
[SNOTICE] = LOG_NOTICE,
[SINFO] = LOG_INFO,
[SDEBUG] = LOG_DEBUG
};
static const char* log_str[] = {
[SCRIT] = "CRITICAL",
[SWARNING] = "WARNING",
[SNOTICE] = "NOTICE",
[SINFO] = "INFO",
[SDEBUG] = "DEBUG"
};
void bulkdata_log(int priority, const char *format, ...)
{
va_list vl;
if (priority <= bulkdata_main.log_level) {
time_t t = time(NULL);
struct tm tm = *localtime(&t);
va_start(vl, format);
printf("%d-%02d-%02d %02d:%02d:%02d [bulkdata] %s - ", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, log_str[priority]);
vprintf(format, vl);
va_end(vl);
printf("\n");
openlog("bulkdata", 0, LOG_DAEMON);
va_start(vl, format);
vsyslog(log_syslogmap[priority], format, vl);
va_end(vl);
closelog();
}
}

28
bulkdata/src/log.h Normal file
View File

@@ -0,0 +1,28 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Copyright (C) 2020 iopsys Software Solutions AB
* Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
*
*/
#ifndef __LOG_H
#define __LOG_H
#define DEFAULT_LOGLEVEL SINFO
enum bulkdata_log_level_enum {
SCRIT,
SWARNING,
SNOTICE,
SINFO,
SDEBUG,
__MAX_SLOG
};
void bulkdata_log(int priority, const char *format, ...);
#endif //__LOG_H

336
bulkdata/src/report.c Normal file
View File

@@ -0,0 +1,336 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Copyright (C) 2020 iopsys Software Solutions AB
* Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
* Author: Omar Kallel <omar.kallel@pivasoftware.com>
*
*/
#include "report.h"
static void add_new_json_obj(json_object *json_obj, char *name, char *data, char *type)
{
json_object *jobj;
if(strstr(type, "unsignedInt") || strstr(type, "int") || strstr(type, "long"))
jobj = json_object_new_int64(atoi(data));
else if(strstr(type, "bool"))
jobj = json_object_new_boolean(atoi(data));
else
jobj = json_object_new_string(data);
json_object_object_add(json_obj, name, jobj);
}
static void create_json_bulkdata_report_object_hierarchy(struct profile *profile, char **report)
{
struct json_object *json_obj, *json_obj1, *json_obj2;
struct resultsnode *p;
int i, j, profile_param_number = profile->profile_parameter_number;
char *param_name, *result, *pch, *pchr, *collection_time = NULL;
char buf[1024] = {0};
json_obj = json_object_new_object();
get_time_stamp(profile->json_encoding_report_time_stamp, &collection_time);
if(collection_time) {
if(strcmp(profile->json_encoding_report_time_stamp, "iso8601") == 0)
json_object_object_add(json_obj, "CollectionTime", json_object_new_string(collection_time));
else
json_object_object_add(json_obj, "CollectionTime", json_object_new_int64(atoi(collection_time)));
free(collection_time);
}
json_obj2 = json_obj;
for (i = 0; i < profile_param_number; i++) {
LIST_HEAD(results_list);
bulkdata_get_value_results(profile->profile_parameter[i].reference, &results_list);
list_for_each_entry(p, &results_list, list) {
char *argv[128] = {0};
j = 0;
param_name = get_bulkdata_profile_parameter_name(profile->profile_parameter[i].reference, profile->profile_parameter[i].name, p->name);
strcpy(buf, param_name);
for (pch = strtok_r(buf, ".", &pchr); pch != NULL; pch = strtok_r(NULL, ".", &pchr)) {
argv[j] = pch;
json_obj1 = (json_object *)bbf_api_dmjson_select_obj(json_obj, argv);
if (json_obj1)
json_obj2 = json_obj1;
else {
if (pchr != NULL && *pchr != '\0') {
json_object *new_obj = json_object_new_object();
json_object_object_add(json_obj2, pch, new_obj);
json_obj2 = new_obj;
}
else
add_new_json_obj(json_obj2, pch, p->data, p->type);
}
j++;
}
}
bulkdata_free_data_from_list(&results_list);
FREE(param_name);
}
result = (char *)json_object_to_json_string_ext(json_obj, JSON_C_TO_STRING_PRETTY);
*report = strdup(result);
json_object_put(json_obj);
}
static void create_json_bulkdata_report_name_value_pair(struct profile *profile, char **report)
{
struct json_object *json_obj;
struct resultsnode *p;
char *param_name, *result, *collection_time = NULL;
int i = 0, profile_param_number = profile->profile_parameter_number;
json_obj = json_object_new_object();
get_time_stamp(profile->json_encoding_report_time_stamp, &collection_time);
if(collection_time) {
if(strcmp(profile->json_encoding_report_time_stamp, "iso8601") == 0)
json_object_object_add(json_obj, "CollectionTime", json_object_new_string(collection_time));
else
json_object_object_add(json_obj, "CollectionTime", json_object_new_int64(atoi(collection_time)));
free(collection_time);
}
for (i = 0; i < profile_param_number; i++) {
LIST_HEAD(results_list);
bulkdata_get_value_results(profile->profile_parameter[i].reference, &results_list);
list_for_each_entry(p, &results_list, list) {
param_name = get_bulkdata_profile_parameter_name(profile->profile_parameter[i].reference, profile->profile_parameter[i].name, p->name);
add_new_json_obj(json_obj, param_name, p->data, p->type);
FREE(param_name);
}
bulkdata_free_data_from_list(&results_list);
}
result = (char *)json_object_to_json_string_ext(json_obj, JSON_C_TO_STRING_PRETTY);
*report = strdup(result);
json_object_put(json_obj);
}
static void add_failed_reports_to_report_json(struct profile *profile, char *new_report, char **report, int isnext)
{
json_object *json_obj, *json_array, *json_string;
struct failed_reports *retreport = NULL;
char *msgout = NULL;
int j = 0;
json_obj = json_object_new_object();
json_array = json_object_new_array();
json_object_object_add(json_obj,"Report", json_array);
if(list_empty(profile->failed_reports))
goto new_report;
list_for_each_entry(retreport, profile->failed_reports, list) {
if(!j && isnext) {
j = 1;
continue;
}
json_string = json_tokener_parse(retreport->freport);
json_object_array_add(json_array, json_string);
}
new_report :
if(new_report) {
json_string = json_tokener_parse(new_report);
json_object_array_add(json_array, json_string);
}
msgout = (char *)json_object_to_json_string_ext(json_obj, JSON_C_TO_STRING_PRETTY);
*report = strdup(msgout);
json_object_put(json_obj);
}
static void create_report_json(char *new_report, char **report)
{
json_object *json_obj, *json_array, *json_string;
char *msgout = NULL;
json_obj = json_object_new_object();
json_array = json_object_new_array();
json_object_object_add(json_obj,"Report", json_array);
if(new_report) {
json_string = json_tokener_parse(new_report);
json_object_array_add(json_array, json_string);
}
msgout = (char *)json_object_to_json_string_ext(json_obj, JSON_C_TO_STRING_PRETTY);
*report = strdup(msgout);
json_object_put(json_obj);
}
int create_json_bulkdata_report(struct profile *profile, char **report)
{
/*
* create json msg of current report
* parse failed reports list and add it to the report
* then add new report to the report
*/
char *msgout;
profile->new_report = NULL;
if(strcmp(profile->json_encoding_report_format, "objecthierarchy") == 0) {
create_json_bulkdata_report_object_hierarchy(profile, &msgout);
} else if(strcmp(profile->json_encoding_report_format, "namevaluepair") == 0) {
create_json_bulkdata_report_name_value_pair(profile, &msgout);
}
if(profile->nbre_of_retained_failed_reports != 0) {
if(profile->nbre_failed_reports >= profile->nbre_of_retained_failed_reports && profile->nbre_of_retained_failed_reports > 0)
add_failed_reports_to_report_json(profile, msgout, report, 1);
else
add_failed_reports_to_report_json(profile, msgout, report, 0);
} else {
create_report_json(msgout, report);
}
append_string_to_string(msgout, &profile->new_report);
FREE(msgout);
return 0;
}
int create_csv_bulkdata_report(struct profile *profile, char **report)
{
/*
* create csv msg of current report
* parse failed reports list and add it to the report
*/
int i;
struct resultsnode *p;
char *str1 = NULL, *str2 = NULL, *str = NULL, *paramprofilename, *timestamp = NULL, *type = NULL, rowseparator = '\0', separator = '\0';
if(strcmp(profile->csv_encoding_row_separator, "&#10;") == 0)
rowseparator = '\n';
else if(strcmp(profile->csv_encoding_row_separator, "&#13;") == 0)
rowseparator = '\r';
if(profile->csv_encoding_field_separator)
separator = profile->csv_encoding_field_separator[0];
get_time_stamp(profile->csv_encoding_row_time_stamp, &timestamp);
/*
* Create header ReportTimestamp,ParameterName,ParameterValue,ParameterType in case of ParameterPerRow
*/
if(strcmp(profile->csv_encoding_report_format, "row") == 0) {
if(timestamp == NULL)
asprintf(&str, "ParameterName%cParameterValue%cParameterType%c", separator, separator, rowseparator);
else
asprintf(&str, "ReportTimestamp%cParameterName%cParameterValue%cParameterType%c", separator, separator, separator, rowseparator);
append_string_to_string(str, report);
FREE(str);
if(profile->nbre_of_retained_failed_reports != 0) {
if(profile->nbre_failed_reports >= profile->nbre_of_retained_failed_reports && profile->nbre_of_retained_failed_reports > 0)
add_failed_reports_to_report_csv(profile, report, 1);
else
add_failed_reports_to_report_csv(profile, report, 0);
}
}
if(strcmp(profile->csv_encoding_report_format, "column") == 0 && timestamp != NULL) {
if(profile->nbre_of_retained_failed_reports != 0) {
if(profile->nbre_failed_reports >= profile->nbre_of_retained_failed_reports && profile->nbre_of_retained_failed_reports > 0)
add_failed_reports_to_report_csv(profile, report, 1);
else
add_failed_reports_to_report_csv(profile, report, 0);
}
append_string_to_string("ReportTimestamp", &str1);
append_string_to_string(timestamp, &str2);
}
/*
* Add New reports
*/
profile->new_report = NULL;
for(i = 0; i < profile->profile_parameter_number; i++) {
LIST_HEAD(results_list);
bulkdata_get_value_results(profile->profile_parameter[i].reference, &results_list);
list_for_each_entry(p, &results_list, list) {
paramprofilename = get_bulkdata_profile_parameter_name(profile->profile_parameter[i].reference, profile->profile_parameter[i].name, p->name);
if(strcmp(profile->csv_encoding_report_format, "row") == 0) {
type = strstr(p->type, ":");
if(timestamp == NULL)
asprintf(&str, "%s%c%s%c%s%c", paramprofilename, separator, p->data, separator, type+1, rowseparator);
else
asprintf(&str, "%s%c%s%c%s%c%s%c", timestamp, separator, paramprofilename, separator, p->data, separator, type+1, rowseparator);
append_string_to_string(str, report);
append_string_to_string(str, &profile->new_report);
FREE(str);
} else if(strcmp(profile->csv_encoding_report_format, "column") == 0) {
if(str1 == NULL || strlen(str1) <= 0)
asprintf(&str, "%s", paramprofilename);
else
asprintf(&str, "%c%s", separator, paramprofilename);
append_string_to_string(str, &str1);
FREE(str);
if(str2 == NULL || strlen(str2) <= 0)
asprintf(&str, "%s", p->data);
else
asprintf(&str, "%c%s", separator, p->data);
append_string_to_string(str, &str2);
FREE(str);
}
FREE(paramprofilename);
}
bulkdata_free_data_from_list(&results_list);
}
if(strcmp(profile->csv_encoding_report_format, "column") == 0) {
asprintf(&str, "%c", rowseparator);
append_string_to_string(str, &str1);
append_string_to_string(str, &str2);
append_string_to_string(str1, report);
append_string_to_string(str2, report);
append_string_to_string(str1, &profile->new_report);
append_string_to_string(str2, &profile->new_report);
}
FREE(str);
FREE(str1);
FREE(str2);
FREE(timestamp);
return 0;
}
static void create_json_failed_report(struct profile *profile, char **report)
{
add_failed_reports_to_report_json(profile, NULL, report, 0);
}
static void create_csv_failed_report(struct profile *profile, char **report)
{
char rowseparator = '\0', separator = '\0', *timestamp = NULL;
if(strcmp(profile->csv_encoding_row_separator, "&#10;") == 0) {
rowseparator = '\n';
} else if(strcmp(profile->csv_encoding_row_separator, "&#13;") == 0) {
rowseparator = '\r';
}
if(profile->csv_encoding_field_separator)
separator = profile->csv_encoding_field_separator[0];
get_time_stamp(profile->csv_encoding_row_time_stamp, &timestamp);
if(strcmp(profile->csv_encoding_report_format, "row") == 0) {
if(timestamp == NULL)
asprintf(report, "ParameterName%cParameterValue%cParameterType%c", separator, separator, rowseparator);
else
asprintf(report, "ReportTimestamp%cParameterName%cParameterValue%cParameterType%c", separator, separator, separator, rowseparator);
}
add_failed_reports_to_report_csv(profile, report, 0);
}
void create_encoding_bulkdata_report(struct profile *profile, char **report)
{
if(strcasecmp(profile->encoding_type, "json") == 0) {
create_json_bulkdata_report(profile, report);
} else if(strcasecmp(profile->encoding_type, "csv") == 0) {
create_csv_bulkdata_report(profile, report);
}
}
void create_failed_report(struct profile *profile, char **report)
{
if(strcasecmp(profile->encoding_type, "json") == 0) {
create_json_failed_report(profile, report);
} else if(strcasecmp(profile->encoding_type, "csv") == 0) {
create_csv_failed_report(profile, report);
}
}

24
bulkdata/src/report.h Normal file
View File

@@ -0,0 +1,24 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Copyright (C) 2020 iopsys Software Solutions AB
* Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
* Author: Omar Kallel <omar.kallel@pivasoftware.com>
*
*/
#ifndef __REPORT_H_
#define __REPORT_H_
#include <json-c/json.h>
#include "common.h"
#include "times.h"
#include "config.h"
void create_encoding_bulkdata_report(struct profile *profile, char **report);
void create_failed_report(struct profile *profile, char **report);
#endif /* __REPORT_H_ */

62
bulkdata/src/times.c Normal file
View File

@@ -0,0 +1,62 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Copyright (C) 2020 iopsys Software Solutions AB
* Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
*
*/
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "times.h"
const char *bulkdata_get_time(void)
{
static char local_time[64];
time_t t_time = time(NULL);
struct tm *t_tm = localtime(&t_time);
if (t_tm == NULL)
return NULL;
if (strftime(local_time, sizeof(local_time),"Date: %a, %d %b %Y %X%z GMT", t_tm) == 0)
return NULL;
return local_time;
}
void get_time_stamp(const char *format, char **timestamp)
{
time_t now = time(NULL);
if (strcmp(format, "unix") == 0) {
asprintf(timestamp, "%ld", now);
} else if (strcmp(format, "iso8601") == 0) {
char buf[32] = {0};
struct tm *ts = localtime(&now);
strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S%Z", ts);
asprintf(timestamp, "%s", buf);
} else
timestamp = NULL;
}
unsigned int get_next_period(time_t time_reference, int reporting_interval)
{
unsigned int next_period;
time_t now = time(NULL);
if (now > time_reference)
next_period = reporting_interval - ((now - time_reference) % reporting_interval);
else
next_period = (time_reference - now) % reporting_interval;
if (next_period == 0)
next_period = reporting_interval;
return next_period;
}

19
bulkdata/src/times.h Normal file
View File

@@ -0,0 +1,19 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Copyright (C) 2020 iopsys Software Solutions AB
* Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
*
*/
#ifndef __TIMES_H
#define __TIMES_H
const char *bulkdata_get_time(void);
void get_time_stamp(const char *format, char **timestamp);
unsigned int get_next_period(time_t time_reference, int reporting_interval);
#endif /* __TIMES_H */

View File

@@ -1,7 +1,4 @@
#!/bin/sh /etc/rc.common
#
# Copyright (C) 2015 inteno.org
#
START=71
USE_PROCD=1

View File

@@ -1,53 +0,0 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=cifsd-tools
PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/namjaejeon/cifsd-tools.git
PKG_SOURCE_DATE:=2019-02-14
PKG_SOURCE_VERSION:=a7d7dfc40524b88dbcb2052034a75f446b3cefdd
PKG_MIRROR_HASH:=a74f95a79c3cdcc78e66c080729141abee0d821e21a326d88b11d849738314fb
PKG_MAINTAINER:=Andy Walsh <andy.walsh44+github@gmail.com>
PKG_LICENSE:=GPL-2.0
PKG_LICENSE_FILES:=COPYING
PKG_INSTALL:=1
PKG_FIXUP:=autoreconf
PKG_REMOVE_FILES:=autogen.sh aclocal.m4
include $(INCLUDE_DIR)/package.mk
include $(INCLUDE_DIR)/nls.mk
define Package/cifsd-tools
SECTION:=net
CATEGORY:=Network
SUBMENU:=Filesystem
TITLE:=Kernel CIFS/SMB server support and userspace tools
DEPENDS:=+kmod-fs-cifsd +glib2 +libnl-core +libnl-genl $(ICONV_DEPENDS)
endef
define Package/cifsd-tools/description
Userspace tools (cifsd, cifsadmin) for the CIFS/SMB kernel fileserver.
The config file location is /etc/cifs/smb.conf
endef
define Package/cifsd-tools/install
$(INSTALL_DIR) $(1)/usr/lib
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libcifsdtools.so* $(1)/usr/lib/
$(INSTALL_DIR) $(1)/etc/cifs
$(INSTALL_CONF) $(PKG_BUILD_DIR)/smb.conf.example $(1)/etc/cifs
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_CONF) ./files/cifsd.config $(1)/etc/config/cifsd
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) ./files/cifsd.init $(1)/etc/init.d/cifsd
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/{cifsadmin,cifsd} $(1)/usr/sbin/
endef
$(eval $(call BuildPackage,cifsd-tools))

View File

@@ -1,9 +0,0 @@
config global 'global'
option server_string 'CIFSD on OpenWRT'
option ipc_timeout '8' # IPC timeout is used as a workaround for uninterruptible sleep until this is fixed upstream.
config share
option name 'share'
option comment 'Default guest share'
option path '/mnt'
option guest_ok 'yes'

View File

@@ -1,161 +0,0 @@
#!/bin/sh /etc/rc.common
START=90
USE_PROCD=1
PROG=/usr/sbin/cifsd
USER_DB=/etc/cifs/cifsdpwd.db
CIFS_ADMIN=cifsadmin
EXTRA_COMMANDS="users"
EXTRA_HELP=" users Show list of users created by cifsadmin"
users() {
[ -f "$USER_DB" ] && cut -d ':' $USER_DB -f1 || \
printf "No users available.\n"
}
validate_cifsd_global() {
uci_validate_section cifsd global global \
'server_string:string' \
'workgroup:string' \
'netbios_name:string' \
'interface:string' \
'ipc_timeout:uinteger'
}
validate_cifsd_share() {
uci_validate_section cifsd share "${1}" \
'name:string' \
'comment:string' \
'path:string' \
'guest_ok:bool' \
'read_only:bool' \
'allow_hosts:list' \
'deny_hosts:list' \
'users:string' \
'invalid_users:string' \
'create_mask:string' \
'dir_mask:string' \
'max_connections:uinteger' \
'veto_files:list'
}
validate_cifsd_users() {
uci_validate_section cifsd users "${1}" \
'user:string' \
'password:string' \
'desc:string'
}
load_cifsd_global() {
local server_string
local workgroup
local netbios_name
local ipc_timeout
validate_cifsd_global
echo -e "[global]" >> /var/etc/cifsd.conf
[ -n "$server_string" ] && echo -e "\tserver string = $server_string" >> /var/etc/cifsd.conf
[ -n "$workgroup" ] && echo -e "\tworkgroup = $workgroup" >> /var/etc/cifsd.conf
[ -n "$netbios_name" ] && echo -e "\tnetbios name = $netbios_name" >> /var/etc/cifsd.conf
[ -n "$ipc_timeout" ] && echo -e "\tipc timeout name = $ipc_timeout" >> /var/etc/cifsd.conf || \
echo -e "\tipc timeout name = 8" >> /var/etc/cifsd.conf
}
load_cifsd_share() {
local name
local comment
local path
local guest_ok
local allow_hosts
local deny_hosts
local users
local invalid_users
local max_connections
local veto_files
local dir_mask
local create_mask
local read_only
validate_cifsd_share ${1}
if [ -z "$name" -o -z "$path" ]; then
logread -t ${0} "Missing name or path."
return
fi
echo -e "\n[$name]\n\tpath = $path" >> /var/etc/cifsd.conf
[ -n "$comment" ] && echo -e "\tcomment = $comment" >> /var/etc/cifsd.conf
[ -n "$guest_ok" ] && echo -e "\tguest ok = $guest_ok" >> /var/etc/cifsd.conf
[ -n "$allow_hosts" ] && echo -e "\tallow hosts = $allow_hosts" >> /var/etc/cifsd.conf
[ -n "$deny_hosts" ] && echo -e "\tdeny hosts = $deny_hosts" >> /var/etc/cifsd.conf
[ -n "$users" ] && echo -e "\tvalid users = $users" >> /var/etc/cifsd.conf
[ -n "$invalid_users" ] && echo -e "\tinvalid users = $invalid_users" >> /var/etc/cifsd.conf
[ -n "$max_connections" ] && echo -e "\tmax connections = $max_connections" >> /var/etc/cifsd.conf
[ -n "$create_mask" ] && echo -e "\tcreate mask = $create_mask" >> /var/etc/cifsd.conf
[ -n "$dir_mask" ] && echo -e "\tdirectory mask = $dir_mask" >> /var/etc/cifsd.conf
if [ -n "$read_only" ]; then
echo -e "\tread only = $read_only" >> /var/etc/cifsd.conf
if [ "${read_only}" -eq "0" ]; then
echo -e "\twrite ok = 1" >> /var/etc/cifsd.conf
fi
else
echo -e "\twrite ok = 1" >> /var/etc/cifsd.conf
fi
[ -n "$veto_files" ] && echo -e "\tveto files = $veto_files" >> /var/etc/cifsd.conf
}
load_cifsd_users() {
local user
local password
local desc
validate_cifsd_users ${1}
[ $(which ${CIFS_ADMIN}) ] || {
logread -t ${0} "${CIFS_ADMIN} tools is not available"
return;
}
cifsadmin -a "${user}" -p "${password}"
if [ "$?" -ne 0 ]; then
logread -t ${0} "Failed to create/update ${user}"
fi
}
service_triggers()
{
procd_add_config_trigger "config.change" "cifsd" /etc/init.d/cifsd restart
}
init_config() {
[ -f "/var/etc/cifsd.conf" ] && rm /var/etc/cifsd.conf
config_load cifsd
load_cifsd_global
# Delete existing users
[ -f "${USER_DB}" ] && {
rm -f "${USER_DB}"
}
config_foreach load_cifsd_users users
config_foreach load_cifsd_share share
}
start_service() {
. /lib/functions.sh
init_config
[ ! "$(grep cifsd /proc/modules)" ] && modprobe cifsd
procd_open_instance
procd_set_param command /usr/bin/env LANG=en_US.UTF-8 $PROG -c /var/etc/cifsd.conf
procd_set_param respawn
procd_close_instance
}
stop_service() {
killall cifsd
# IPC timeout will kill the remaining processes.
}

View File

@@ -1,73 +0,0 @@
For some reason, fs.h on Inteno kernel is missing inode->i_mutex nesting subclasses for the lock validator
which is triggering implicit declaration error. To workaround this hardcore use of mutex_lock by removing
kernel version check.
---
--- a/vfs.c
+++ b/vfs.c
@@ -544,15 +544,9 @@ int cifsd_vfs_setattr(struct cifsd_work
attrs->ia_valid |= ATTR_CTIME;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
- inode_lock(inode);
- err = notify_change(dentry, attrs, NULL);
- inode_unlock(inode);
-#else
mutex_lock(&inode->i_mutex);
err = notify_change(dentry, attrs, NULL);
mutex_unlock(&inode->i_mutex);
-#endif
if (update_size)
put_write_access(inode);
@@ -753,11 +747,8 @@ int cifsd_vfs_remove_file(char *name)
if (!dir->d_inode)
goto out;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
- inode_lock_nested(dir->d_inode, I_MUTEX_PARENT);
-#else
mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
-#endif
+
dentry = lookup_one_len(last, dir, strlen(last));
if (IS_ERR(dentry)) {
err = PTR_ERR(dentry);
@@ -783,11 +774,7 @@ int cifsd_vfs_remove_file(char *name)
dput(dentry);
out_err:
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
- inode_unlock(dir->d_inode);
-#else
mutex_unlock(&dir->d_inode->i_mutex);
-#endif
out:
path_put(&parent);
return err;
@@ -1302,11 +1289,8 @@ int cifsd_vfs_unlink(struct dentry *dir,
int err = 0;
dget(dentry);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
- inode_lock(dir->d_inode);
-#else
mutex_lock(&dir->d_inode->i_mutex);
-#endif
+
if (!dentry->d_inode || !dentry->d_inode->i_nlink) {
err = -ENOENT;
goto out;
@@ -1318,11 +1302,8 @@ int cifsd_vfs_unlink(struct dentry *dir,
err = vfs_unlink(dir->d_inode, dentry, NULL);
out:
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
- inode_unlock(dir->d_inode);
-#else
mutex_unlock(&dir->d_inode->i_mutex);
-#endif
+
dput(dentry);
if (err)
cifsd_debug("failed to delete, err %d\n", err);

View File

@@ -1,60 +0,0 @@
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=cifsd
PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/namjaejeon/cifsd.git
PKG_SOURCE_DATE:=2019-03-05
PKG_SOURCE_VERSION:=e1715ce125d55b125b1b58a6f1819ef8e54cc3ba
PKG_MIRROR_HASH:=521585ebfda0ecc02372b1a38ebf762fbbcead6d0b754a47599a5bf6bfdb3fb6
PKG_MAINTAINER:=Andy Walsh <andy.walsh44+github@gmail.com>
PKG_LICENSE:=GPL-2.0
PKG_LICENSE_FILES:=COPYING
include $(INCLUDE_DIR)/package.mk
define KernelPackage/fs-cifsd
SUBMENU:=Filesystems
TITLE:=CIFS/SMB kernel server support
FILES:=$(PKG_BUILD_DIR)/cifsd.$(LINUX_KMOD_SUFFIX)
DEPENDS+= \
+kmod-nls-base \
+kmod-nls-utf8 \
+kmod-crypto-md4 \
+kmod-crypto-md5 \
+kmod-crypto-hmac \
+kmod-crypto-ecb \
+kmod-crypto-des \
+kmod-crypto-sha256 \
+kmod-crypto-cmac \
+kmod-crypto-sha512 \
+kmod-crypto-aead \
+kmod-crypto-ccm
KCONFIG:= \
CONFIG_KEYS=y \
CONFIG_CRYPTO_ARC4=y
endef
define KernelPackage/fs-cifsd/description
Kernel module for a CIFS/SMBv2,3 fileserver.
endef
TARGET_CFLAGS+= -DCONFIG_CIFSD_ACL
MAKE_OPTS:=\
ARCH="$(LINUX_KARCH)" \
CROSS_COMPILE="$(TARGET_CROSS)" \
M="$(PKG_BUILD_DIR)"
define Build/Compile
$(MAKE) -C "$(LINUX_DIR)" \
$(MAKE_OPTS) \
CFLAGS="$(TARGET_CFLAGS)" \
CONFIG_CIFS_SERVER=m \
modules
endef
$(eval $(call KernelPackage,fs-cifsd))

View File

@@ -1,69 +0,0 @@
--- a/vfs.c
+++ b/vfs.c
@@ -544,15 +544,9 @@ int cifsd_vfs_setattr(struct cifsd_work
attrs->ia_valid |= ATTR_CTIME;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
- inode_lock(inode);
- err = notify_change(dentry, attrs, NULL);
- inode_unlock(inode);
-#else
mutex_lock(&inode->i_mutex);
err = notify_change(dentry, attrs, NULL);
mutex_unlock(&inode->i_mutex);
-#endif
if (update_size)
put_write_access(inode);
@@ -753,11 +747,8 @@ int cifsd_vfs_remove_file(char *name)
if (!dir->d_inode)
goto out;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
- inode_lock_nested(dir->d_inode, I_MUTEX_PARENT);
-#else
mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
-#endif
+
dentry = lookup_one_len(last, dir, strlen(last));
if (IS_ERR(dentry)) {
err = PTR_ERR(dentry);
@@ -783,11 +774,7 @@ int cifsd_vfs_remove_file(char *name)
dput(dentry);
out_err:
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
- inode_unlock(dir->d_inode);
-#else
mutex_unlock(&dir->d_inode->i_mutex);
-#endif
out:
path_put(&parent);
return err;
@@ -1302,11 +1289,8 @@ int cifsd_vfs_unlink(struct dentry *dir,
int err = 0;
dget(dentry);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
- inode_lock(dir->d_inode);
-#else
mutex_lock(&dir->d_inode->i_mutex);
-#endif
+
if (!dentry->d_inode || !dentry->d_inode->i_nlink) {
err = -ENOENT;
goto out;
@@ -1318,11 +1302,8 @@ int cifsd_vfs_unlink(struct dentry *dir,
err = vfs_unlink(dir->d_inode, dentry, NULL);
out:
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
- inode_unlock(dir->d_inode);
-#else
mutex_unlock(&dir->d_inode->i_mutex);
-#endif
+
dput(dentry);
if (err)
cifsd_debug("failed to delete, err %d\n", err);

View File

@@ -24,7 +24,7 @@ What we need is the public key for the clients.
For dropbear "dropbearkey -y -f files/etc/dropbear/logid" will generate the public key.
----------
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCwn9RaDAzxW1dTmIhXgFBnpi1lhj8xhYpCVQiPxxdk9IEmH8zjo4y9j3sPkqKOlRnkwjpZIpLEKBnpQTwVIMCU/AG7nDJX3OH9RfS9mLJQLfFL8HyGCyqDezFWldbyovhJZvdUeK4tAXJWv2W3OVHiz2L8IlncBgP/E9DJElsyhhQHsM96UE6tBkXsvXkoDbMSYXFcLbgiUwBKfmM2BF/aPDL45iznGur7/2j9v95PwJ0gtMu9jjNRq+pXCXhTh3bsnczm0MpZC1aiRc9nJAeGIMmhrf15E4jBKgTnrstzJxGVAdajKeR954KcNsS33cS2Wmui2YjmPbBXjqf1frzJ log@inteno
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCwn9RaDAzxW1dTmIhXgFBnpi1lhj8xhYpCVQiPxxdk9IEmH8zjo4y9j3sPkqKOlRnkwjpZIpLEKBnpQTwVIMCU/AG7nDJX3OH9RfS9mLJQLfFL8HyGCyqDezFWldbyovhJZvdUeK4tAXJWv2W3OVHiz2L8IlncBgP/E9DJElsyhhQHsM96UE6tBkXsvXkoDbMSYXFcLbgiUwBKfmM2BF/aPDL45iznGur7/2j9v95PwJ0gtMu9jjNRq+pXCXhTh3bsnczm0MpZC1aiRc9nJAeGIMmhrf15E4jBKgTnrstzJxGVAdajKeR954KcNsS33cS2Wmui2YjmPbBXjqf1frzJ log@iopsys
----------
The public key should be just one line. Add that line to the

65
dectmngr/Makefile Normal file
View File

@@ -0,0 +1,65 @@
#
# Copyright (C) 2020 IOPSYS Software Solutions AB
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=dectmngr
PKG_RELEASE:=1
PKG_VERSION:=1.0
LOCAL_DEV=1
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/dectmngr.git
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=2c8990fd5275d469e8ab6c7a99e17fe0a56052ea
endif
PKG_LICENSE:=GPLv2
PKG_LICENSE_FILES:=LICENSE
RSTRIP:=true
export BUILD_DIR
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_BUILD_PARALLEL:=1
include $(INCLUDE_DIR)/package.mk
define Package/$(PKG_NAME)
CATEGORY:=Utilities
TITLE:=DECT Manager
DEPENDS:= +libubox +ubus +libpicoevent
endef
define Package/$(PKG_NAME)/description
DECT manager is a daemon that provides UBUS RPC objects and sends UBUS events for communication with the DECT chip.
endef
ifeq ($(LOCAL_DEV),1)
define Build/Prepare
$(CP) -r src/* $(PKG_BUILD_DIR)/
endef
endif
MAKE_FLAGS += \
CFLAGS+="-Wall"
define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_DIR) $(1)/usr/lib
$(INSTALL_DIR) $(1)/etc/dect/
$(INSTALL_DIR) $(1)/etc/config/
$(INSTALL_DIR) $(1)/etc/init.d/
$(INSTALL_BIN) $(PKG_BUILD_DIR)/app/dectmngr $(1)/usr/sbin/
$(STRIP) $(1)/usr/sbin/dectmngr
$(INSTALL_BIN) $(PKG_BUILD_DIR)/app/libdect.so $(1)/usr/lib/
$(STRIP) $(1)/usr/lib/libdect.so
endef
$(eval $(call BuildPackage,$(PKG_NAME)))

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,4 @@
9c5962fc5bdef309d15cf76dd2678297 out4/Images/PRODUCT_IOPSYS/DCX81_fw_c/MOD/USB/DCX81_MOD_USB.ITCM
17d4a7e4021c6089104c28c228245df2 out4/Images/PRODUCT_IOPSYS/DCX81_fw_c/MOD/USB/DCX81_MOD_USB.ITCM_L
d32e2a3dd05f4d1933eac77cfff091ba out4/Images/PRODUCT_IOPSYS/DCX81_fw_c/MOD/USB/DCX81_MOD_USB.bin
477bfa4e91914db4c0078b31a6cdf208 out4/Images/PRODUCT_IOPSYS/DCX81_fw_c/MOD/USB/DCX81_MOD_USB.BOOTLOADER.bin

View File

@@ -0,0 +1 @@
{0xee,0xb7,0x3c,0x8f,0x44,0xe1,0xad,0x87,0x53,0xc8,0x57,0x4e,0x08,0x6d,0x87,0x9f}

View File

@@ -0,0 +1,984 @@
<html>
<head>
<title>EEPROM map </title>
<style>
<!--
th {
font-size: 12px;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-style: bold;
}
td {
font-size: 10px;
font-family: Verdana, Arial, Helvetica, sans-serif;
}
body {
background-color: #FFFFFF;
}
-->
</style>
</head>
<body>
<h1>EEPROM map bsd02eep.h-GIT</h1>
<table border="2" cellspacing="2" width="100%" rules="both" align="center" style=" font-size: 10px;
font-family: Verdana, Arial, Helvetica, sans-serif;
background-color: #C9FFDA;
border-collapse: collapse;
border: 5px solid white">
<tbody>
<tr style=" font-size: 12px;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-style: bold;
background-color: #78FF95"><td>Name</td><td align="center">Offset</td><td>Comment</td><td width="100">Default</td></tr>
<tr><td>SD02_RESERVED1[4]</td><td align="center">0(0x0)</td><td> L4 RESERVED1 </td><td width="100"></td></tr>
<tr><td>SD02_RESERVED2[5]</td><td align="center">4(0x4)</td><td> L5 RESERVED2 </td><td width="100"></td></tr>
<tr><td>SD02_SUB_GFSK[10]</td><td align="center">9(0x9)</td><td> L10 </td><td width="100">0x80,0x80,0x80,0x80,0x80,
0x80,0x80,0x80,0x80,0x80,
</td></tr>
<tr><td>SD02_PREAM_NORMAL</td><td align="center">19(0x13)</td><td> L1 </td><td width="100">0x65,
</td></tr>
<tr><td>SD02_TEST_FLAGS</td><td align="center">20(0x14)</td><td> L1 If set: bit 0: BMP Driver Recover disabled
bit 1: Watchdog not enabled
bit 3: disable activity led </td><td width="100">0x00,
</td></tr>
<tr><td>SD02_EMC_MODEL[3]</td><td align="center">21(0x15)</td><td> L3 EMC number and model, transfered in MODEL_ID IE </td><td width="100">0x0F,0xEB,0x02,
</td></tr>
<tr><td>SD02_RVREF</td><td align="center">24(0x18)</td><td> L1 </td><td width="100">0x1F,
</td></tr>
<tr><td>SD02_TEST_MODE</td><td align="center">25(0x19)</td><td> L1 Enter TBR6/10 </td><td width="100">0x00,
</td></tr>
<tr><td>SD02_RXTUN</td><td align="center">26(0x1A)</td><td> L1 FR </td><td width="100">0x70,
</td></tr>
<tr><td>SD02_AUXBGPROG</td><td align="center">27(0x1B)</td><td> L1 AUXBGPROG (Bandgap calibration value) </td><td width="100">0x66,
</td></tr>
<tr><td>SD02_RVDDC</td><td align="center">28(0x1C)</td><td> L1 </td><td width="100">0x97,
</td></tr>
<tr><td>SD02_POWER_CONTROL</td><td align="center">29(0x1D)</td><td> L1 Power Control: nibble usage (0xsw) where s is ARM clock speed and w the number of
pflash waitstates.
Note: For ICELP, the default ARM clock
speed is 64 (96MHz and 4 wait states).
Note: For VegaOne s is used as an index to
recommended clock settings (see
VegaOne_AHB_PLLDIV[16] in file
cdr17tim.c).
For VegaOne: bit 3 is used to select if flash
running in syncrounous (asyncronous = 0
syncronous = 1)</td><td width="100">0x2,
</td></tr>
<tr><td>SD02_WDCT_HOP_CONTROL</td><td align="center">30(0x1E)</td><td> L1 </td><td width="100">0x00,
</td></tr>
<tr><td>SD02_WDCT_QUAL_CONTROL</td><td align="center">31(0x1F)</td><td> L1 WDCT Quality Control: When the most significant bit of this byte is
set to 1, the hop sequence of 19 and frequency
substitution can be disabled.</td><td width="100">0x00,
</td></tr>
<tr><td>SD02_US_DECT</td><td align="center">32(0x20)</td><td> L1 </td><td width="100">0x00,
</td></tr>
<tr><td>SD02_MAX_USABLE_RSSI</td><td align="center">33(0x21)</td><td> L1 </td><td width="100">0x78,
</td></tr>
<tr><td>SD02_LOWER_RSSI_LIMIT</td><td align="center">34(0x22)</td><td> L1 </td><td width="100">0x50,
</td></tr>
<tr><td>SD02_V22_VOL_HIGH</td><td align="center">35(0x23)</td><td> L1 V22 Volume Low - Sidetone </td><td width="100">0x01,
</td></tr>
<tr><td>SD02_V22_VOL_LOW</td><td align="center">36(0x24)</td><td> L1 V22 Volume High - Sidetone </td><td width="100">0x00,
</td></tr>
<tr><td>SD02_DSP_CID_THRES</td><td align="center">37(0x25)</td><td> L1 CID Threshold</td><td width="100">0x51,
</td></tr>
<tr><td>SD02_DSP_PATCH[50]</td><td align="center">38(0x26)</td><td> L50 DSP patch area 8 entries, each defines a flexible value for 1
DSP parameter.
Structure:
1st Word: DSP instance (low, high byte)
2nd Word: offset (low, high byte)
3rd Word: value (low, high byte)</td><td width="100">0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,
</td></tr>
<tr><td>SD02_ARM_PATCH[40]</td><td align="center">88(0x58)</td><td> L40: 0=unused ARM patch area (5 entries): 5 X 2 X4 Bytes to modify any 30 bit ARM
address location after protocol stack initialisation:
1st Word: address (big endian)
2nd Word: value (big endian)
The 2 MSBits of the address define the
write access type:
00: Word access (u32)
01: Halfword access (u16)
10: Byte access (u8) </td><td width="100">0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,
</td></tr>
<tr><td>SD02_DSP_CLOCK</td><td align="center">128(0x80)</td><td> L1 </td><td width="100">0x02,
</td></tr>
<tr><td>SD02_FWROM_BOARDER</td><td align="center">129(0x81)</td><td> L1 </td><td width="100">0x1D,
</td></tr>
<tr><td>SD02_PORBGCFG</td><td align="center">130(0x82)</td><td> L1 PORBGCFG (POR calibration value) </td><td width="100">0xC0,
</td></tr>
<tr><td>SD02_FPTR</td><td align="center">131(0x83)</td><td> L1 MSB used to enable/disable use of this parameter 0=enable </td><td width="100">0xFF,
</td></tr>
<tr><td>SD02_FULL_POWER</td><td align="center">132(0x84)</td><td> DTPC Full Power </td><td width="100">0x7F,
</td></tr>
<tr><td>SD02_LOW_POWER</td><td align="center">133(0x85)</td><td> DTPC Low(medium) Power </td><td width="100">0xC4,
</td></tr>
<tr><td>SD02_LOWEST_POWER</td><td align="center">134(0x86)</td><td> DTPC Lowest Power</td><td width="100">0x03,
</td></tr>
<tr><td>SD02_AEC_LSP_ATTEN_RANGE[2]</td><td align="center">135(0x87)</td><td> L2 AEC_lsp_atten_range For all AEC parameters see User Manual
Vega-Family ARM DSP RELEASE V7.5
(or higher)</td><td width="100">0x00, 0x08,
</td></tr>
<tr><td>SD02_AEC_NLMS_ERL[2]</td><td align="center">137(0x89)</td><td> L2 </td><td width="100">0x40, 0x00,
</td></tr>
<tr><td>SD02_AEC_X_CLIP[2]</td><td align="center">139(0x8B)</td><td> L2 </td><td width="100">0x0F, 0x1F,
</td></tr>
<tr><td>SD02_AEC_ECHO_RATIO[2]</td><td align="center">141(0x8D)</td><td> L2 </td><td width="100">0x00, 0x01,
</td></tr>
<tr><td>SD02_AEC_DENS_GAMMA_E_HIGH[2]</td><td align="center">143(0x8F)</td><td> L2 </td><td width="100">0xCC, 0x01,
</td></tr>
<tr><td>SD02_AEC_DENS_GAMMA_E_LOW[2]</td><td align="center">145(0x91)</td><td> L2 </td><td width="100">0x80, 0x00,
</td></tr>
<tr><td>SD02_AEC_DENS_GAMMA_E_DT[2]</td><td align="center">147(0x93)</td><td> L2 </td><td width="100">0x66, 0x01,
</td></tr>
<tr><td>SD02_AEC_DENS_GAMMA_N[2]</td><td align="center">149(0x95)</td><td> L2 </td><td width="100">0x00, 0x01,
</td></tr>
<tr><td>SD02_AEC_DENS_TAIL_ALPHA[2]</td><td align="center">151(0x97)</td><td> L2 </td><td width="100">0x66, 0x66,
</td></tr>
<tr><td>SD02_AEC_DENS_TAIL_PORTION[2]</td><td align="center">153(0x99)</td><td> L2 </td><td width="100">0xD7, 0x03,
</td></tr>
<tr><td>SD02_AEC_DENS_NL_ATTEN[2]</td><td align="center">155(0x9B)</td><td> L2 </td><td width="100">0x00, 0x08,
</td></tr>
<tr><td>SD02_AEC_DENS_CNI_LEVEL[2]</td><td align="center">157(0x9D)</td><td> L2 </td><td width="100">0x00, 0x20,
</td></tr>
<tr><td>SD02_AEC_MODE[2]</td><td align="center">159(0x9F)</td><td> L2 </td><td width="100">0xF7, 0x00,
</td></tr>
<tr><td>SD02_AEC_ECHO_PATH_DELAY[2]</td><td align="center">161(0xA1)</td><td> L2 </td><td width="100">0x00, 0x00,
</td></tr>
<tr><td>SD02_DTPC_ENABLE</td><td align="center">163(0xA3)</td><td></td><td width="100">0x01,
</td></tr>
<tr><td>SD02_RSSI_TIMER</td><td align="center">164(0xA4)</td><td></td><td width="100">0x64,
</td></tr>
<tr><td>SD02_DRPC_RSSI_THRESH</td><td align="center">165(0xA5)</td><td></td><td width="100">0x80,
</td></tr>
<tr><td>SD02_DRPC_RSSI_CORRECT</td><td align="center">166(0xA6)</td><td></td><td width="100">0x1C,
</td></tr>
<tr><td>SD02_RVR2C_INIT</td><td align="center">167(0xA7)</td><td> L1 </td><td width="100">0x40,
</td></tr>
<tr><td>SD02_FI_TRIG_GPIO</td><td align="center">168(0xA8)</td><td> L1 </td><td width="100">0x0,
</td></tr>
<tr><td>SD02_RF19APU_SUPPORT_FCC</td><td align="center">169(0xA9)</td><td> L1 </td><td width="100">0x0,
</td></tr>
<tr><td>SD02_RF19APU_TC_DELAY</td><td align="center">170(0xAA)</td><td> L1 </td><td width="100">0x3,
</td></tr>
<tr><td>SD02_RF19APU_GAP_DELAY</td><td align="center">171(0xAB)</td><td> L1 </td><td width="100">0x8,
</td></tr>
<tr><td>SD02_RF19APU_GAP_DELAY_FADOFF</td><td align="center">172(0xAC)</td><td> L1 </td><td width="100">0xA,
</td></tr>
<tr><td>SD02_RF19APU_TRSSI_DELAY</td><td align="center">173(0xAD)</td><td> L1 </td><td width="100">0x25,
</td></tr>
<tr><td>SD02_RF19APU_TRSSI_DELAY_FADOFF</td><td align="center">174(0xAE)</td><td> L1 </td><td width="100">0x13,
</td></tr>
<tr><td>SD02_RF19APU_DEVIATION</td><td align="center">175(0xAF)</td><td> L1 </td><td width="100">0x13,
</td></tr>
<tr><td>SD02_RF19APU_ATEST</td><td align="center">176(0xB0)</td><td> L1 </td><td width="100">0xF,
</td></tr>
<tr><td>SD02_RF19APU_DTEST</td><td align="center">177(0xB1)</td><td> L1 </td><td width="100">0x00,
</td></tr>
<tr><td>SD02_RF19APU_PA2_COMP</td><td align="center">178(0xB2)</td><td> L1 </td><td width="100">0x3C,
</td></tr>
<tr><td>SD02_RF19APU_PA_ON</td><td align="center">179(0xB3)</td><td> L1 </td><td width="100">0x33,
</td></tr>
<tr><td>SD02_RF19APU_GAIN</td><td align="center">180(0xB4)</td><td> L1 </td><td width="100">0x0,
</td></tr>
<tr><td>SD02_RF19APU_MLSE</td><td align="center">181(0xB5)</td><td>L1 Bit Meaning 0 MLSE active
1 Dynamic MLSE active
2 MLSE CLK Polarity
3 MLSE deviation 0 <20> 288, 1 <20> 360
4 4 bit field giving MLSE delay in bits
5 If set to 0 <20> delay defaults to 9
6 <20>
7 <20>
</td><td width="100">0x1,
</td></tr>
<tr><td>SD02_RF19APU_KCALOVR</td><td align="center">182(0xB6)</td><td>L1 </td><td width="100">0x0,
</td></tr>
<tr><td>SD02_RF19APU_KCALOVR_LINEAR</td><td align="center">183(0xB7)</td><td>L1 Linear KCAL correction, 4 LSB A factor (KCALOVR_A) 4 MSB B factor (KCALOVR_B)</td><td width="100">0x88,
</td></tr>
<tr><td>SD02_RF19APU_BEACON_LP</td><td align="center">184(0xB8)</td><td>L1 Bit0 - Enable. Bit1-7 - Value of power when HS on cradle</td><td width="100">0xC1,
</td></tr>
<tr><td>SD02_RF19APU_GENERIC_ADD1[2]</td><td align="center">185(0xB9)</td><td> L2 </td><td width="100">0x00,0x00,
</td></tr>
<tr><td>SD02_RF19APU_GENERIC_ADD2[2]</td><td align="center">187(0xBB)</td><td> L2 </td><td width="100">0x00,0x00,
</td></tr>
<tr><td>SD02_RF19APU_GENERIC_ADD3[2]</td><td align="center">189(0xBD)</td><td> L2 </td><td width="100">0x00,0x00,
</td></tr>
<tr><td>SD02_RF19APU_GENERIC_ADD4[2]</td><td align="center">191(0xBF)</td><td> L2 </td><td width="100">0x00,0x00,
</td></tr>
<tr><td>SD02_RF19APU_GENERIC_CONTROL</td><td align="center">193(0xC1)</td><td>L1 bit [1:0] = control of SD02_RF19APU_GENERIC_ADD1
bit [3:2] = control of SD02_RF19APU_GENERIC_ADD2
bit [5:4] = control of
SD02_RF19APU_GENERIC_ADD3
bit [7:6] = control of SD02_RF19APU_GENERIC_ADD4
for each of the above:
if 0 (or 3): use the appropriate register as RF indirect mapping 0~256
if 1: use the appropriate register as direct space mapping 0 <20> 104
if 2: use the appropriate register as analog indirect space mapping 0 <20> 69
</td><td width="100">0x00,
</td></tr>
<tr><td>SD02_FNR_N_LOW[2]</td><td align="center">194(0xC2)</td><td> L2 FNR SD02_FNR_N_LOW </td><td width="100">0x00,0x01,
</td></tr>
<tr><td>SD02_FNR_N_HIGH[2]</td><td align="center">196(0xC4)</td><td> L2 FNR SD02_FNR_N_HIGH </td><td width="100">0x40,0x01,
</td></tr>
<tr><td>SD02_FNR_NR_LIMIT[2]</td><td align="center">198(0xC6)</td><td> L2 FNR SD02_FNR_NR_LIMIT </td><td width="100">0x00,0x28,
</td></tr>
<tr><td>SD02_FNR_spDETCC[2]</td><td align="center">200(0xC8)</td><td> L2 FNR SD02_FNR_spDETCC </td><td width="100">0x00,0x02,
</td></tr>
<tr><td>SD02_FNR_Ton_detect[2]</td><td align="center">202(0xCA)</td><td> L2 FNR SD02_FNR_Ton_detect </td><td width="100">0x00,0x06,
</td></tr>
<tr><td>SD02_CR_OPTIONS</td><td align="center">204(0xCC)</td><td> L1 - Bit 0-1: Codec preferred (0-G726,1-G727,other reserved)
Bit 2: Action in Normal - unused
Bit 3: Action in Protected - unused
Bit 4: Opt G726 - activate improved - unused
Bit 5-6: Mode (0-Auto,1-Normal,2-Protected,3-Reserved) - not relevant in FT
Bit 7: Enable/Disable.
</td><td width="100">0x81,
</td></tr>
<tr><td>SD02_CR_SB_PATT</td><td align="center">205(0xCD)</td><td>L1 - Padding option for SB (i.e. nibble) either 4 bits or 8 bitsfor WB codecs </td><td width="100">0xFF,
</td></tr>
<tr><td>SD02_CR_FB_PATT</td><td align="center">206(0xCE)</td><td>L1 - Padding option for FB (i.e. all frame) either 4 bits or 8 bits for WB codecs </td><td width="100">0xFF,
</td></tr>
<tr><td>SD02_CR_START_MUTE_NR</td><td align="center">207(0xCF)</td><td>L1 - Number of errors to start full frame mute </td><td width="100">0x1E,
</td></tr>
<tr><td>SD02_CR_STOP_MUTE_NR</td><td align="center">208(0xD0)</td><td>L1 - Number of errors to stop full frame mute </td><td width="100">0x0F,
</td></tr>
<tr><td>SD02_CR_DECAY[2]</td><td align="center">209(0xD1)</td><td>L2 - First Byte - Decay MSB, Second byte : Decay LSB (in Q12) </td><td width="100">0x0F,
0xD4,
</td></tr>
<tr><td>SD02_CR_SATURATION</td><td align="center">211(0xD3)</td><td>L1 - Saturation value for FB filter </td><td width="100">0x28,
</td></tr>
<tr><td>SD02_CR_MSG</td><td align="center">212(0xD4)</td><td>L1 - Nr of Frames before msg mute/unmute </td><td width="100">0x1E,
</td></tr>
<tr><td>SD02_CONTROL</td><td align="center">213(0xD5)</td><td>L1 - Enable Clock Divider Selection</td><td width="100">0x00,
</td></tr>
<tr><td>SD02_CLK_DIV[3]</td><td align="center">214(0xD6)</td><td>L3 - Clock Divider Setting </td><td width="100">0x00,0x00,0x00,
</td></tr>
<tr><td>SD02_CLK_SEL[2]</td><td align="center">217(0xD9)</td><td>L2 - Clock Selection </td><td width="100">0x00,0x00,
</td></tr>
<tr><td>SD02_AHB_PLL_SETTING_LOW[4]</td><td align="center">219(0xDB)</td><td>L4 - AHB PLL LOW Setting </td><td width="100">0x00,0x00,0x00,0x00,
</td></tr>
<tr><td>SD02_AHB_PLL_SETTING_MED[4]</td><td align="center">223(0xDF)</td><td>L4 - AHB PLL MED Setting </td><td width="100">0x00,0x00,0x00,0x00,
</td></tr>
<tr><td>SD02_AHB_PLL_SETTING_HIGH[4]</td><td align="center">227(0xE3)</td><td>L4 - AHB PLL HIGH Setting </td><td width="100">0x00,0x00,0x00,0x00,
</td></tr>
<tr><td>SD02_CP_FEATURES</td><td align="center">231(0xE7)</td><td>L1 - CP features Setting </td><td width="100">0x00,
</td></tr>
<tr><td>SD02_CP_CONFIGURATION_OFFSET</td><td align="center">232(0xE8)</td><td>Bit 0: If set, SYPO alignment is offset by 1 slot,Bit 2: Dummy Merge to first traffic</td><td width="100">0x00,
</td></tr>
<tr><td>SD02_CP_ULE_FLAGS</td><td align="center">233(0xE9)</td><td> L1 - Phase 1: 0x2, Phase 1.2: 0x6 ,Phase 2: 0xA, Phase 3: 0xE</td><td width="100">0x0A,
</td></tr>
<tr><td>SD02_DUMMY_BEARER_THRES_ADAPT_THRESH</td><td align="center">234(0xEA)</td><td></td><td width="100">0x58,
</td></tr>
<tr><td>SD02_RF19APUZ_EXT_LNA</td><td align="center">235(0xEB)</td><td>L1 - CP features Setting </td><td width="100">0x00,
</td></tr>
<tr><td>SD02_RFIC_SELECTION</td><td align="center">236(0xEC)</td><td>L1 - CP features Setting </td><td width="100">0x01,
</td></tr>
<tr><td>SD02_UNUSED_210</td><td align="center">237(0xED)</td><td> L1 </td><td width="100">0x00,
</td></tr>
<tr><td>SD02_PHS_SCAN_PARAM</td><td align="center">238(0xEE)</td><td> JDECT parameters: RSSI threshold for PHS detection. PHS scan every 10 seconds. </td><td width="100">0x0C,
</td></tr>
<tr><td>SD02_JDECT_LEVEL1_M82</td><td align="center">239(0xEF)</td><td> minus 82 dBm RSSI threshold for Japan regulation </td><td width="100">0x0B,
</td></tr>
<tr><td>SD02_JDECT_LEVEL2_M62</td><td align="center">240(0xF0)</td><td> minus 62 dBm RSSI threshold for Japan regulation </td><td width="100">0x11,
</td></tr>
<tr><td>SD02_JDECT_CERTAINTY_PARAM</td><td align="center">241(0xF1)</td><td> PHS detection Certainty parameters.(upper nibble reduces miss detection. lower nibble reduces false alaram) </td><td width="100">0x55,
</td></tr>
<tr><td>SD02_ULE_DUMMY_TRAF_THRESH</td><td align="center">242(0xF2)</td><td>L1 - Threshold for dummy traffic bearer merge</td><td width="100">0x03,
</td></tr>
<tr><td>SD02_PWR_ADC_INPUT</td><td align="center">243(0xF3)</td><td> L1 Input source of the Auxiliary A/D </td><td width="100">0x0E,
</td></tr>
<tr><td>SD02_PWR_POR_INPUT</td><td align="center">244(0xF4)</td><td> L1 Input source of the POR A/D </td><td width="100">0x16,
</td></tr>
<tr><td>SD02_RES_FACTOR</td><td align="center">245(0xF5)</td><td> L1 Resistor Factor on AUX input </td><td width="100">0x02,
</td></tr>
<tr><td>SD02_UART_DELAY_TIMER</td><td align="center">246(0xF6)</td><td>L1 - Selects the timer in 10 msec to delay UART</td><td width="100">0x00,
</td></tr>
<tr><td>SD02_V21_VOL_HIGH</td><td align="center">247(0xF7)</td><td>L2 SD02_V21_VOL_HIGH </td><td width="100">0x01,
</td></tr>
<tr><td>SD02_V21_VOL_LOW</td><td align="center">248(0xF8)</td><td>L2 SD02_V21_VOL_LOW </td><td width="100">0x00,
</td></tr>
<tr><td>SD02_PRODUCTION_TEST_RSSI_THRESH_DOWNLINK</td><td align="center">249(0xF9)</td><td>L1 SD02_PRODUCTION_TEST_RSSI_THRESH_DOWNLINK </td><td width="100">0x88,
</td></tr>
<tr><td>SD02_PRODUCTION_TEST_RSSI_THRESH_UPLINK</td><td align="center">250(0xFA)</td><td>L1 SD02_PRODUCTION_TEST_RSSI_THRESH_UPLINK </td><td width="100">0x88,
</td></tr>
<tr><td>SD02_FIXED_CARRIER_OFFSET</td><td align="center">251(0xFB)</td><td>L1 SD02_FIXED_CARRIER_OFFSET - Bit(0..5) : Carrier to use ,
Bit(6) : Enable fixed PM carrier ,
Bit(7) : Seta fixed carrier [bit(0..4)] in RF file. When using this option you MUST set PP+FP with the same carrier.
</td><td width="100">0x00,
</td></tr>
<tr><td>SD02_TEMP_MEASURE_TIME</td><td align="center">252(0xFC)</td><td>L1 SD02_TEMP_MEASURE_TIME. bit 0-1 temperature measurement period for VCAL. 2 bits for 4 values 0,1,2,3 == 5,1,2,3 minutes. default value == 0
</td><td width="100">0x00,
</td></tr>
<tr><td>FNCA_DRV_UNUSED</td><td align="center">253(0xFD)</td><td> <----------- unused </td><td width="100">0xCC,</td></tr>
<tr><td>SD02_SMS_FW_VERSION[6]</td><td align="center">253(0xFD)</td><td> L6 </td><td width="100">0xCC,0x21,0x10,0x20,0x03,0xCC,
</td></tr>
<tr><td>SD02_SMS_SMTE_RESOURCES</td><td align="center">259(0x103)</td><td> L1 </td><td width="100">0x11,
</td></tr>
<tr><td>SD02_SMS_BREAK_SMS_CALL</td><td align="center">260(0x104)</td><td> L1 </td><td width="100">0x00,
</td></tr>
<tr><td>SD02_SMS_SUBADDR_MASK[2]</td><td align="center">261(0x105)</td><td> L2 </td><td width="100">0x00,0x03,
</td></tr>
<tr><td>SD02_SMS_MIN_BYTES_FREE</td><td align="center">263(0x107)</td><td> L1 </td><td width="100">0x28,
</td></tr>
<tr><td>SD02_SMS_SMSC_OFFHOOK</td><td align="center">264(0x108)</td><td> L1 </td><td width="100">0x14,
</td></tr>
<tr><td>SD02_SMS_SMSC_ESTABLISH</td><td align="center">265(0x109)</td><td> L1 </td><td width="100">0x14,
</td></tr>
<tr><td>SD02_SMS_HACK_CODE</td><td align="center">266(0x10A)</td><td> L1 </td><td width="100">0x10,
</td></tr>
<tr><td>SD02_SMS_TIMER_T2[2]</td><td align="center">267(0x10B)</td><td> L2 </td><td width="100">0x02,0xF8,
</td></tr>
<tr><td>SD02_SMS_TIMER_T3[2]</td><td align="center">269(0x10D)</td><td> L2 </td><td width="100">0x02,0xEE,
</td></tr>
<tr><td>SD02_SMS_TIMER_T6[2]</td><td align="center">271(0x10F)</td><td> L2 </td><td width="100">0x00,0x14,
</td></tr>
<tr><td>SD02_SMS_TIMER_T10</td><td align="center">273(0x111)</td><td> L1 </td><td width="100">0x0A,
</td></tr>
<tr><td>SD02_SMS_TIMER_T10BIS</td><td align="center">274(0x112)</td><td> L1 </td><td width="100">0x35,
</td></tr>
<tr><td>SD02_SMS_FSK_FREQ0[2]</td><td align="center">275(0x113)</td><td> L2 </td><td width="100">0x00,0x15,
</td></tr>
<tr><td>SD02_SMS_FSK_FREQ1[2]</td><td align="center">277(0x115)</td><td> L2 </td><td width="100">0x00,0x0D,
</td></tr>
<tr><td>SD02_SMS_FSK_CIT_VOL[2]</td><td align="center">279(0x117)</td><td> L2 </td><td width="100">0x13,0x00,
</td></tr>
<tr><td>SD02_SMS_FSK_TIMER_PREAM</td><td align="center">281(0x119)</td><td> L1 </td><td width="100">0x0D,
</td></tr>
<tr><td>SD02_SMS_PROT_RESP_TYPE</td><td align="center">282(0x11A)</td><td> L1 </td><td width="100">0x80,
</td></tr>
<tr><td>SD02_SMS_PROT_BEARER_CAP[20]</td><td align="center">283(0x11B)</td><td> L20 </td><td width="100">0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,
</td></tr>
<tr><td>SD02_SMS_PROT(k)[42]</td><td align="center">303(0x12F)</td><td> 21 * Nr_of_Protocols. Where 21 is the length of protocol. </td><td width="100">0x80,
0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,
0x80,
0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,
</td></tr>
<tr><td>SD02_SMS_SMSC_SETTINGS</td><td align="center">345(0x159)</td><td> L1 </td><td width="100">0x12,
</td></tr>
<tr><td>SD02_SMS_SMSC_VALIDITY_TIME</td><td align="center">346(0x15A)</td><td> L1 </td><td width="100">0x03,
</td></tr>
<tr><td>SD02_SMS_SMSC_EMAIL_SEP</td><td align="center">347(0x15B)</td><td> L1 Email Separator</td><td width="100">0x20,
</td></tr>
<tr><td>SD02_SMS_SMSC_OPERATOR</td><td align="center">348(0x15C)</td><td> L1 </td><td width="100">0x00,
</td></tr>
<tr><td>SD02_SMS_SMSC_UNUSED[2]</td><td align="center">349(0x15D)</td><td> L2 </td><td width="100">0x00,0x00,
</td></tr>
<tr><td>SD02_SMS_SMSC_INC_NUM[8]</td><td align="center">351(0x15F)</td><td> L8 </td><td width="100">0x04,0x21,0x1F,0xFF,
0xFF,0xFF,0xFF,0xFF,
</td></tr>
<tr><td>SD02_SMS_SMSC_OUT_NUM[8]</td><td align="center">359(0x167)</td><td> L8 </td><td width="100">0x42,0x11,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,
</td></tr>
<tr><td>SD02_SMS_SMSC_EMAIL_NUM[8]</td><td align="center">367(0x16F)</td><td> L8 </td><td width="100">0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,
</td></tr>
<tr><td>SD02_SMS_SMSC(i)[90]</td><td align="center">375(0x177)</td><td> SMSC area end SMSC * 30. Where 30 is the length of data for one SMSC </td><td width="100">0x01,
0x03,
0x20,
0x00,
0x00,0x00,
0x01,0x93,0x01,0x0F,
0xFF,0xFF,0xFF,0xFF,
0x01,0x93,0x01,0x0F,
0xFF,0xFF,0xFF,0xFF,
0x08,0x00,0xF0,0xFF,
0xFF,0xFF,0xFF,0xFF,
0x01,
0x03,
0x20,
0x00,
0x00,0x00,
0x20,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,
0x20,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,
0x01,
0x03,
0x20,
0x05,
0x00,0x00,
0x01,0x90,0x01,0x50,
0x4F,0xFF,0xFF,0xFF,
0x01,0x90,0x01,0x50,
0x4F,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,
</td></tr>
<tr><td>SD02_ACV10_VOLUME[2]</td><td align="center">465(0x1D1)</td><td> L2 ACV10 Volume Control for SPK 2 bytes </td><td width="100">0x08,0x00,
</td></tr>
<tr><td>FNCA_SMS_UNUSED[2]</td><td align="center">467(0x1D3)</td><td> <----------- unused </td><td width="100"></td></tr>
<tr><td>SD02_CALL_BARRING[30]</td><td align="center">469(0x1D5)</td><td> L30 call barring data </td><td width="100"></td></tr>
<tr><td>SD02_MASTER_PIN[4]</td><td align="center">499(0x1F3)</td><td> L4 master mode pin code, reset value e.g. FF FF 15 90 </td><td width="100">0xFF,0xFF,0x15,0x90,
</td></tr>
<tr><td>SD02_AC[4]</td><td align="center">503(0x1F7)</td><td> L4 authentication code, e.g. FF FF 15 90</td><td width="100">0xFF,0xFF,0x00,0x00,
</td></tr>
<tr><td>SD02_RING_ON_OFF</td><td align="center">507(0x1FB)</td><td> L1 ring on/off enabled </td><td width="100">0x00,
</td></tr>
<tr><td>SD02_ULE_AC[4]</td><td align="center">508(0x1FC)</td><td> L4 ULE authentication code, e.g. FF FF 00 00</td><td width="100">0xFF,0xFF,0x00,0x00,
</td></tr>
<tr><td>SD02_EEPROM0_END</td><td align="center">512(0x200)</td><td></td><td width="100"></td></tr>
<tr><td>SD02_BOOT_DELAY</td><td align="center">513(0x201)</td><td> L1 Boot up delay in seconds </td><td width="100"></td></tr>
<tr><td>SD02_HAN_START_FILE_0[8514]</td><td align="center">514(0x202)</td><td><a href="bhanEepromDefaults.html">HAN EEPROM Block</a> </td><td width="100"></td></tr>
<tr><td>SD02_HAN_END_FILE_0</td><td align="center">9028(0x2344)</td><td> HAN EEPROM Block End</td><td width="100"></td></tr>
<tr><td>SD02_ULE_SUB_IPUI[5]</td><td align="center">9029(0x2345)</td><td> L5 Data: IPUI </td><td width="100"></td></tr>
<tr><td>SD02_ULE_SUB_TPUI[3]</td><td align="center">9034(0x234A)</td><td> L3 Data: TPUI </td><td width="100"></td></tr>
<tr><td>SD02_ULE_SUB_DCK[16]</td><td align="center">9037(0x234D)</td><td> L16 Data: DCK </td><td width="100"></td></tr>
<tr><td>SD02_ULE_SUB_UAK[16]</td><td align="center">9053(0x235D)</td><td> L16 Data: UAK </td><td width="100"></td></tr>
<tr><td>SD02_ULE_SUB_AC[4]</td><td align="center">9069(0x236D)</td><td> L4 Data: authentication code AC </td><td width="100"></td></tr>
<tr><td>SD02_ULE_SUB_UAK_AUTH</td><td align="center">9073(0x2371)</td><td> L1 Data: UAK authorization </td><td width="100"></td></tr>
<tr><td>SD02_ULE_SUB_STATUS</td><td align="center">9074(0x2372)</td><td> L1 Data: status </td><td width="100"></td></tr>
<tr><td>SD02_ULE_SUB_HANDSET_NR</td><td align="center">9075(0x2373)</td><td> L1 Data: handset number </td><td width="100"></td></tr>
<tr><td>SD02_ULE_SUB_DCK_ASSIGNED[2]</td><td align="center">9076(0x2374)</td><td> L1 Data: DCK assigned </td><td width="100"></td></tr>
<tr><td>SD02_ULE_SUB_FEATURES</td><td align="center">9078(0x2376)</td><td> L1 CP Features </td><td width="100"></td></tr>
<tr><td>SD02_ULE_SUB_DEFCK[16]</td><td align="center">9079(0x2377)</td><td> L16 Data: Default Cipher Key </td><td width="100"></td></tr>
<tr><td>SD02_ULE_SUB_DEFCK_ASSIGNED</td><td align="center">9095(0x2387)</td><td> L1 Data: DefCK assigned </td><td width="100"></td></tr>
<tr><td>SD02_ULE_SUB_CCM_CK[16]</td><td align="center">9096(0x2388)</td><td> L16 Data: CCM Key for ULE </td><td width="100"></td></tr>
<tr><td>SD02_ULE_SUB_DLC_OPERATING_MODE</td><td align="center">9112(0x2398)</td><td> L1 ULE DLC operating mode </td><td width="100"></td></tr>
<tr><td>SD02_ULE_SUB_HL_FEATURES</td><td align="center">9113(0x2399)</td><td> L1 ULE HL features </td><td width="100"></td></tr>
<tr><td>SD02_ULE_SUB_RESERVED[4]</td><td align="center">9114(0x239A)</td><td> L4 Reserved for future use </td><td width="100"></td></tr>
<tr><td>SD02_ULE_SUB_NEXT_RX_SEQUENCE_NUMBER[3]</td><td align="center">9118(0x239E)</td><td> L3 RX Sequence number </td><td width="100"></td></tr>
<tr><td>SD02_ULE_SUB_NEXT_TX_SEQUENCE_NUMBER[3]</td><td align="center">9121(0x23A1)</td><td> L3 TX Sequence number </td><td width="100"></td></tr>
<tr><td>SD02_ULE_SUB_OVER_A_FIELD_NEXT_RX_SEQUENCE_NUMBER[3]</td><td align="center">9124(0x23A4)</td><td> L3 RX Sequence number </td><td width="100"></td></tr>
<tr><td>SD02_ULE_SUB_OVER_A_FIELD_NEXT_TX_SEQUENCE_NUMBER</td><td align="center">9127(0x23A7)</td><td> L3 TX Sequence number </td><td width="100"></td></tr>
<tr><td>SD02_ULE_SUB_LEN[13978]</td><td align="center">101(0x65)</td><td> End of first subscribtion </td><td width="100"></td></tr>
<tr><td>SD02_ULE_SUB_UNUSED[5]</td><td align="center">14079(0x36FF)</td><td> <----------- unused </td><td width="100"></td></tr>
<tr><td>SD02_MD5_SIGNATURE[16]</td><td align="center">14084(0x3704)</td><td> L16 16 bytes of MD5 signature</td><td width="100"></td></tr>
<tr><td>SD02_MD5_END</td><td align="center">14100(0x3714)</td><td> L0</td><td width="100"></td></tr>
<tr><td>SD02_MD5_UNUSED</td><td align="center">14093(0x370D)</td><td> <----------- unused </td><td width="100"></td></tr>
<tr><td>FNCA_MMI_UNUSED[7]</td><td align="center">14093(0x370D)</td><td> <----------- unused </td><td width="100"></td></tr>
<tr><td>SD02_SUB_LAL</td><td align="center">14100(0x3714)</td><td> L1 </td><td width="100">0x24,
</td></tr>
<tr><td>SD02_SUB_Y</td><td align="center">14101(0x3715)</td><td> L1 </td><td width="100">0x24,
</td></tr>
<tr><td>SD02_DSP_CID_MARK_MODE</td><td align="center">14102(0x3716)</td><td> L1 DSP CID start state for mark mode - upper byte (Bits 8-15) </td><td width="100">0x40,
</td></tr>
<tr><td>SD02_DSP_CID_SEIZURE_MODE</td><td align="center">14103(0x3717)</td><td> L1 DSP CID start state for seizure mode - upper byte (Bits 8-15) </td><td width="100">0x40,
</td></tr>
<tr><td>SD02_DSP_THP2_KI[2]</td><td align="center">14104(0x3718)</td><td> L2 DSP THP2 - ki - input scaling factor - Currently unused </td><td width="100">0x10,
0x00,
</td></tr>
<tr><td>SD02_DSP_TXV[2]</td><td align="center">14106(0x371A)</td><td> L2 AUDIO TX volume control </td><td width="100">0x23,
0xBC,
</td></tr>
<tr><td>SD02_DSP_RXV[2]</td><td align="center">14108(0x371C)</td><td> L2 AUDIO RX volume control </td><td width="100">0x10,
0x00,
</td></tr>
<tr><td>SD02_DSP_RLP[2]</td><td align="center">14110(0x371E)</td><td> L2 AUDIO RLP volume control </td><td width="100">0x20,
0x00,
</td></tr>
<tr><td>SD02_AFE_AFELGC1</td><td align="center">14112(0x3720)</td><td> L1 AFE gains </td><td width="100">0x23,
</td></tr>
<tr><td>SD02_AFE_AFEMSGC1_NORMAL</td><td align="center">14113(0x3721)</td><td> L1 AFE gains normal mode </td><td width="100">0x32,
</td></tr>
<tr><td>SD02_MIN_RING_ON</td><td align="center">14114(0x3722)</td><td> min. DAEV_RING_ON </td><td width="100">2,
</td></tr>
<tr><td>SD02_MIN_RING_OFF</td><td align="center">14115(0x3723)</td><td> min. DAEV_RING_OFF </td><td width="100">3,
</td></tr>
<tr><td>SD02_MIN_DTMF_ON</td><td align="center">14116(0x3724)</td><td> min. DAEV_DTMF_ON </td><td width="100">2,
</td></tr>
<tr><td>SD02_MIN_DTMF_OFF</td><td align="center">14117(0x3725)</td><td> min. DAEV_DTMF_OFF </td><td width="100">3,
</td></tr>
<tr><td>SD02_MIN_CPDS_ON</td><td align="center">14118(0x3726)</td><td> min. DAEV_CPDS_ON </td><td width="100">2,
</td></tr>
<tr><td>SD02_MIN_CPDS_OFF</td><td align="center">14119(0x3727)</td><td> min. DAEV_CPDS_OFF </td><td width="100">2,
</td></tr>
<tr><td>SD02_MIN_CPDB_ON</td><td align="center">14120(0x3728)</td><td> min. DAEV_CPDB_ON </td><td width="100">4,
</td></tr>
<tr><td>SD02_MIN_CPDB_OFF</td><td align="center">14121(0x3729)</td><td> min. DAEV_CPDB_OFF </td><td width="100">4,
</td></tr>
<tr><td>SD02_MIN_FXD1_ON</td><td align="center">14122(0x372A)</td><td> min. DAEV_FXD1_ON </td><td width="100">3,
</td></tr>
<tr><td>SD02_MIN_FXD1_OFF</td><td align="center">14123(0x372B)</td><td> min. DAEV_FXD1_OFF </td><td width="100">1,
</td></tr>
<tr><td>SD02_MIN_FXD2_ON</td><td align="center">14124(0x372C)</td><td> min. DAEV_FXD2_ON </td><td width="100">3,
</td></tr>
<tr><td>SD02_MIN_FXD2_OFF</td><td align="center">14125(0x372D)</td><td> min. DAEV_FXD2_OFF </td><td width="100">1,
</td></tr>
<tr><td>SD02_MIN_GTD1_ON</td><td align="center">14126(0x372E)</td><td> min. DAEV_GTD1_ON </td><td width="100">3,
</td></tr>
<tr><td>SD02_MIN_GTD1_OFF</td><td align="center">14127(0x372F)</td><td> min. DAEV_GTD1_OFF </td><td width="100">1,
</td></tr>
<tr><td>SD02_MIN_CAS_ON</td><td align="center">14128(0x3730)</td><td> min. DAEV_CAS_ON </td><td width="100">2,
</td></tr>
<tr><td>SD02_MIN_CAS_OFF</td><td align="center">14129(0x3731)</td><td> min. DAEV_CAS_OFF </td><td width="100">3,
</td></tr>
<tr><td>SD02_MIN_CAS_REQUIRED</td><td align="center">14130(0x3732)</td><td> min. DAEV_CAS_REQUIRED </td><td width="100">0x60,
</td></tr>
<tr><td>SD02_DTMF_ON</td><td align="center">14131(0x3733)</td><td> min. DTMF tone on duration </td><td width="100">40,
</td></tr>
<tr><td>SD02_DTMF_OFF</td><td align="center">14132(0x3734)</td><td> min. pause after DTMF </td><td width="100">40,
</td></tr>
<tr><td>SD02_DIAL_PAUSE</td><td align="center">14133(0x3735)</td><td> min. dial pause </td><td width="100">125,
</td></tr>
<tr><td>SD02_DTMF_VOL_LOW</td><td align="center">14134(0x3736)</td><td> V6dB low DTMF frequency </td><td width="100">0x40,
</td></tr>
<tr><td>SD02_DTMF_VOL_LOW_HIGH</td><td align="center">14135(0x3737)</td><td> V6dB low DTMF frequency high </td><td width="100">0x24,
</td></tr>
<tr><td>SD02_DTMF_VOL_HIGH</td><td align="center">14136(0x3738)</td><td> V6dB high DTMF frequency </td><td width="100">0xB0,
</td></tr>
<tr><td>SD02_DTMF_VOL_HIGH_HIGH</td><td align="center">14137(0x3739)</td><td> V6dB high DTMF frequency high </td><td width="100">0x2D,
</td></tr>
<tr><td>SD02_PULSE_MAKE_LENGTH</td><td align="center">14138(0x373A)</td><td> L1 PSTN:dialPULSE </td><td width="100">40,
</td></tr>
<tr><td>SD02_PULSE_BREAK_LENGTH</td><td align="center">14139(0x373B)</td><td> L1 PSTN:dialPULSE </td><td width="100">60,
</td></tr>
<tr><td>SD02_PULSE_IDP_LENGTH</td><td align="center">14140(0x373C)</td><td> L1 PSTN:dialPULSE </td><td width="100">80,
</td></tr>
<tr><td>SD02_LCURRENT_CYCLE</td><td align="center">14141(0x373D)</td><td> L1 PSTN:PCA1070 </td><td width="100">50,
</td></tr>
<tr><td>SD02_LCURRENT_IDP</td><td align="center">14142(0x373E)</td><td> L1 PSTN:PCA1070 </td><td width="100">32,
</td></tr>
<tr><td>SD02_PAUSE_LENGTH</td><td align="center">14143(0x373F)</td><td> L1 PSTN/AUDIO:dial</td><td width="100">30,
</td></tr>
<tr><td>SD02_FLASH_LENGTH</td><td align="center">14144(0x3740)</td><td> L1 PSTN:dial </td><td width="100">10,
</td></tr>
<tr><td>SD02_EARTH_LENGTH</td><td align="center">14145(0x3741)</td><td> L1 PSTN:dial </td><td width="100">40,
</td></tr>
<tr><td>SD02_RING_MIN</td><td align="center">14146(0x3742)</td><td> L1 PSTN:ringer </td><td width="100">18,
</td></tr>
<tr><td>SD02_RING_MAX</td><td align="center">14147(0x3743)</td><td> L1 PSTN:ringer </td><td width="100">50,
</td></tr>
<tr><td>SD02_RON_DETECT</td><td align="center">14148(0x3744)</td><td> L1 PSTN:ringer </td><td width="100">9,
</td></tr>
<tr><td>SD02_RON_HOLD</td><td align="center">14149(0x3745)</td><td> L1 PSTN:ringer </td><td width="100">20,
</td></tr>
<tr><td>SD02_ROFF_DETECT</td><td align="center">14150(0x3746)</td><td> L1 PSTN:ringer </td><td width="100">11,
</td></tr>
<tr><td>SD02_ROFF_HOLD</td><td align="center">14151(0x3747)</td><td> L1 PSTN:ringer </td><td width="100">25,
</td></tr>
<tr><td>SD02_LIF_CURR_LO</td><td align="center">14152(0x3748)</td><td> L1 PSTN:l.current </td><td width="100">0,
</td></tr>
<tr><td>SD02_LIF_CURR_HI</td><td align="center">14153(0x3749)</td><td> L1 +1 </td><td width="100">0xFF,
</td></tr>
<tr><td>SD02_WETTING_TIME</td><td align="center">14154(0x374A)</td><td> L1 Wetting Pulse </td><td width="100">0x01,
</td></tr>
<tr><td>SD02_DTMF_D_TIME</td><td align="center">14155(0x374B)</td><td> L1 DTMF-D for CAS </td><td width="100">0x23,
</td></tr>
<tr><td>SD02_STUTTER_CYCLES</td><td align="center">14156(0x374C)</td><td> L1 # of Stutter </td><td width="100">0x0A,
</td></tr>
<tr><td>SD02_CID_DET_ENBL_TIME</td><td align="center">14157(0x374D)</td><td> L1 CID detection 100ms steps </td><td width="100">38,
</td></tr>
<tr><td>SD02_FSK_START_TIME</td><td align="center">14158(0x374E)</td><td> L1 CID-2 detection </td><td width="100">0xE0,
</td></tr>
<tr><td>SD02_FSK_OFFHOOK_TIME[2]</td><td align="center">14159(0x374F)</td><td> L2 CID-2 detection </td><td width="100">0xAD,
0x03,
</td></tr>
<tr><td>SD02_AFE_AFEMSGC1_HF</td><td align="center">14161(0x3751)</td><td> L1 AFE gains for Handsfree </td><td width="100">0x32,
</td></tr>
<tr><td>SD02_AFE_AFEMSGC2</td><td align="center">14162(0x3752)</td><td> L1 AFE gains </td><td width="100">0x51,
</td></tr>
<tr><td>SD02_EAR_VOL_TAB[10]</td><td align="center">14163(0x3753)</td><td> L10 10 volume values for polyphonic ringing (increasing order)</td><td width="100">0x02,0x03,0x04,0x06,0x08,
0x09,0x0A,0x0B,0x0c,0x0d,
</td></tr>
<tr><td>SD02_RVBC1C_VAL</td><td align="center">14173(0x375D)</td><td> L1 Codec 1 (In base Spk) control </td><td width="100">0xC0,
</td></tr>
<tr><td>SD02_RVBC1G_VAL</td><td align="center">14174(0x375E)</td><td> L1 Codec 1 (In base Spk) gain </td><td width="100">0x4F,
</td></tr>
<tr><td>SD02_RVBC1C_VAL_HF</td><td align="center">14175(0x375F)</td><td> L1 Codec 1 (In base Spk) control for HF</td><td width="100">0xC0,
</td></tr>
<tr><td>SD02_RVBC1G_VAL_HF</td><td align="center">14176(0x3760)</td><td> L1 Codec 1 (In base Spk) gain for HF</td><td width="100">0x4F,
</td></tr>
<tr><td>SD02_WBE_ENABLE</td><td align="center">14177(0x3761)</td><td> L1 WBE_FT Enable </td><td width="100">0x00,
</td></tr>
<tr><td>SD02_RVDDC_FIX_ENABLE</td><td align="center">14178(0x3762)</td><td> L1 ENABLE/DISABLE Patch for RVDCDC HW bug</td><td width="100">0x00,
</td></tr>
<tr><td>SD02_INBAND_TONE_SELECT</td><td align="center">14179(0x3763)</td><td> L1 Select country for inband tone </td><td width="100">0x00,
</td></tr>
<tr><td>SD02_DRV_UNUSED</td><td align="center">14180(0x3764)</td><td> <----------- unused </td><td width="100">0xFF,</td></tr>
<tr><td>SD02_ALLOC_LINE1[2]</td><td align="center">14180(0x3764)</td><td>handset allocation (see Protocol Interface) bitwise per handset: 1 = handset allocated;
(0xFF 0xFF indicates Collective ringing) for
each of the next 3 lines</td><td width="100">0xFF,0xFF,
</td></tr>
<tr><td>SD02_ALLOC_LINE2[2]</td><td align="center">14182(0x3766)</td><td></td><td width="100">0xFF,0xFF,
</td></tr>
<tr><td>SD02_ALLOC_LINE3[2]</td><td align="center">14184(0x3768)</td><td></td><td width="100">0xFF,0xFF,
</td></tr>
<tr><td>SD02_HS_TYPE_CATIQ30</td><td align="center">14186(0x376A)</td><td> Tells HS is CatIQ30 capable implemented for Max 8 HS only </td><td width="100">0x0,
</td></tr>
<tr><td>SD02_WB_TYPE_HSNR[2]</td><td align="center">14187(0x376B)</td><td> PT WB capability storage Note:For CAT-IQ builds user should not modify this location</td><td width="100">0,0,
</td></tr>
<tr><td>SD02_WB_LINE_TYPE</td><td align="center">14189(0x376D)</td><td> FT Line TYPE storgare(2= G711WB, 1 = WB , 0 =NB) </td><td width="100">0x00,
</td></tr>
<tr><td>SD02_WB_LINE_SUB_TYPE</td><td align="center">14190(0x376E)</td><td> FT WB Line Sub Type ( 0 = G722 WB, 1 = G711 WB) </td><td width="100">0x00,
</td></tr>
<tr><td>SD02_DH_MIX_RATIO</td><td align="center">14191(0x376F)</td><td></td><td width="100">0xFF,
</td></tr>
<tr><td>SD02_NEMO_PTS[2]</td><td align="center">14192(0x3770)</td><td> Two Bytes are used</td><td width="100">0xFF,0xFF,
</td></tr>
<tr><td>SD02_SPK_SLOT_TYPE</td><td align="center">14194(0x3772)</td><td> Slot type for SPK phone</td><td width="100">0x02,
</td></tr>
<tr><td>SD02_MAX_NUM_ACT_CALLS_PT</td><td align="center">14195(0x3773)</td><td> Maximum nmber of active calls of 1 PT.</td><td width="100">0x03,
</td></tr>
<tr><td>SD02_NEMO_DISABLED</td><td align="center">14196(0x3774)</td><td> bit 7 is used for permanent NEMo disable </td><td width="100">0x00,
</td></tr>
<tr><td>SD02_HS_TYPE_CATIQ20[2]</td><td align="center">14197(0x3775)</td><td> L2: Two bytes for CAT-iq 2.0 Handset </td><td width="100">0x00,
0x00,
</td></tr>
<tr><td>SD02_FP_CUSTOM_FEATURES</td><td align="center">14199(0x3777)</td><td> Bit-0: INL 0-enable/1-disable, Bit-1: 0-conf,trfr enable/1-conf,trfr disable</td><td width="100">0x00,
</td></tr>
<tr><td>SD02_ENCRYPT_STATUS</td><td align="center">14200(0x3778)</td><td> L1: Encryption enable/disable</td><td width="100">0x01,
</td></tr>
<tr><td>SD02_MM_CAPABILITIES[10]</td><td align="center">14201(0x3779)</td><td> L10: MM Capabilities for each Handset.FTEEP_NUM_SUB/SD09_MAX_NUM_SUB is hard coded as 10 </td><td width="100">0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,
</td></tr>
<tr><td>SD02_ARBITRARY_TPUI[3]</td><td align="center">14211(0x3783)</td><td> L3 : 3 bytes to store arbitrary TPUI</td><td width="100">0x00,0x00,0x00,
</td></tr>
<tr><td>SD02_HS_TYPE_CATIQ21[2]</td><td align="center">14214(0x3786)</td><td> L2: Two bytes for CAT-iq 2.1 Handset </td><td width="100">0x00,0x00,
</td></tr>
<tr><td>SD02_INTERFERENCE_DETECTION_MEASUREMENT_INTERVAL</td><td align="center">14216(0x3788)</td><td> L1: Interference Detection Measurement Interval </td><td width="100">60,
</td></tr>
<tr><td>SD02_INTERFERENCE_DETECTION_NOISE_INTERVAL</td><td align="center">14217(0x3789)</td><td> L1: Interference Detection Noise Interval </td><td width="100">30,
</td></tr>
<tr><td>SD02_INTERFERENCE_DETECTION_CONFIG1</td><td align="center">14218(0x378A)</td><td> L1: Interference Detection config1, bit 0-7: Active Carriers Mask, carriers 1-8 </td><td width="100">0xFF,
</td></tr>
<tr><td>SD02_INTERFERENCE_DETECTION_CONFIG2</td><td align="center">14219(0x378B)</td><td> L1: Interference Detection config2, bit 0-1: Active Carriers Mask, carriers 9-10; bit7: 1-Enable/0-Disable Interference Detection alg.</td><td width="100">0x83,
</td></tr>
<tr><td>SD02_INTERFERENCE_DETECTION_TRAFFIC_SLOTS_IN_FRAME</td><td align="center">14220(0x378C)</td><td> L1: Interference Detection Traffic Slots In Frame </td><td width="100">0x03,
</td></tr>
<tr><td>SD02_INTERFERENCE_DETECTION_INTERFERENCE_LEVEL</td><td align="center">14221(0x378D)</td><td> L1: Interference Detection Interference Level </td><td width="100">0x98,
</td></tr>
<tr><td>SD02_NEMO_CONTROL</td><td align="center">14222(0x378E)</td><td> L1: MSB enables HM00_NEMO_DUMMY_USE_RSSI_FOR_IF_CHECK, others are for extending NEMO WA bearer time </td><td width="100">0x00,
</td></tr>
<tr><td>FCAC_HLP_END</td><td align="center">14223(0x378F)</td><td> </td><td width="100"></td></tr>
<tr><td>SD02_RINGER_EXPIRY</td><td align="center">14223(0x378F)</td><td> L1 FTMI:X line </td><td width="100">45,
</td></tr>
<tr><td>SD02_LINE_EXPIRY</td><td align="center">14224(0x3790)</td><td> L1 FTMI:release </td><td width="100">85,
</td></tr>
<tr><td>SD02_RINGER_MELODY</td><td align="center">14225(0x3791)</td><td> L1 FTMI:ringer </td><td width="100">9,
</td></tr>
<tr><td>SD02_RINGER_VOLUME</td><td align="center">14226(0x3792)</td><td> L1 FTMI:ringer </td><td width="100">3,
</td></tr>
<tr><td>SD02_DIAL_MODI</td><td align="center">14227(0x3793)</td><td> L1 FTMI:dtmf/reca</td><td width="100">0xD3,
</td></tr>
<tr><td>SD02_DLT_CTRL</td><td align="center">14228(0x3794)</td><td> L1 FTMI:dialTone </td><td width="100">0x3A,
</td></tr>
<tr><td>SD02_TONDET_SEL</td><td align="center">14229(0x3795)</td><td> L1 FTMI:ena/disa enable tone detection features: 0x80: DTAS
0x40: RPAS
0x41: RPASFR
0x20: MFCR</td><td width="100">0x80+0x41+0x20,
</td></tr>
<tr><td>SD02_LRMS_SUPPORT[2]</td><td align="center">14230(0x3796)</td><td> L2 FTMI:LRMS sup. 1 Bit per handset. 1 indicates LMRS support
of the according handset.</td><td width="100">0x00, 0x00,
</td></tr>
<tr><td>SD02_SMS1_PLUS_SUPPORT[2]</td><td align="center">14232(0x3798)</td><td> L2 FTMI:SMS1_PLUS sup. 1 Bit per handset. 1 indicates SMS1+ support
of the according handset.</td><td width="100">0x00, 0x00,
</td></tr>
<tr><td>SD02_COUNTRY_IDENTIFICATION</td><td align="center">14234(0x379A)</td><td> L1 FTMMS </td><td width="100">0x01,
</td></tr>
<tr><td>SD02_SMS_TP_MR</td><td align="center">14235(0x379B)</td><td> L1 FTMMS </td><td width="100">0xfd,
</td></tr>
<tr><td>SD02_DTAM_RING</td><td align="center">14236(0x379C)</td><td> DTAM: ringtones </td><td width="100">0x5,
</td></tr>
<tr><td>SD02_PREF_LINE[9]</td><td align="center">14237(0x379D)</td><td> L9 FTMI:ogo line, up to 9 </td><td width="100">0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
</td></tr>
<tr><td>SD02_PRIOR_HS[30]</td><td align="center">14246(0x37A6)</td><td> L2 FTMI:inc line, up to 3 incoming prioritized HS line 1
ring count of prior. HS line 1
incoming prioritized HS line 2
ring count of prior. HS line 2
incoming prioritized HS line 3
ring count of prior. HS line 3</td><td width="100">0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
</td></tr>
<tr><td>SD02_BLINDCALL_TIM1</td><td align="center">14276(0x37C4)</td><td> Blind call transfer timeout 1 </td><td width="100">0x1E,
</td></tr>
<tr><td>SD02_BLINDCALL_TIM2</td><td align="center">14277(0x37C5)</td><td> Blind call transfer timeout 2 </td><td width="100">0x1E,
</td></tr>
<tr><td>SD02_PARKED_TIM</td><td align="center">14278(0x37C6)</td><td> Parked line timeout </td><td width="100">0x3c,
</td></tr>
<tr><td>SD02_OVERLAP_SEND_TIM</td><td align="center">14279(0x37C7)</td><td> Overlap sending timer </td><td width="100">0x4,
</td></tr>
<tr><td>SD02_DTAM_ENABLE</td><td align="center">14280(0x37C8)</td><td> DTAM: ON/OFF </td><td width="100">0x1,
</td></tr>
<tr><td>SD02_DTAM_ICM_CR</td><td align="center">14281(0x37C9)</td><td> DTAM: codRates ICM </td><td width="100">0xFF,
</td></tr>
<tr><td>SD02_DTAM_OGM_CR</td><td align="center">14282(0x37CA)</td><td> DTAM: codRates OGM </td><td width="100">0xFF,
</td></tr>
<tr><td>SD02_DTAM_PILL_CR</td><td align="center">14283(0x37CB)</td><td> DTAM: codRates Pill</td><td width="100">0xFF,
</td></tr>
<tr><td>SD02_EARVOL</td><td align="center">14284(0x37CC)</td><td> EAR Vol </td><td width="100">0x05,
</td></tr>
<tr><td>SD02_BS_CALL_SCREENING</td><td align="center">14285(0x37CD)</td><td> L1 Call Screening Enable/disable</td><td width="100">0x00,
</td></tr>
<tr><td>SD02_EMC_COMPLIANT[2]</td><td align="center">14286(0x37CE)</td><td> L2 stores the compliant of PT's i.e. whether EMC is equal </td><td width="100">0x00, 0x00,
</td></tr>
<tr><td>SD02_LU10_RN_UPDATE</td><td align="center">14288(0x37D0)</td><td> L1 Enable/disable update RN=SN+1 </td><td width="100">0x05,
</td></tr>
<tr><td>SD02_MMI_DECT_SECURITY</td><td align="center">14289(0x37D1)</td><td> L1 DECT SECURITY LEVEL </td><td width="100">0x00,
</td></tr>
<tr><td>SD02_CR_PREFERRED_CODEC</td><td align="center">14290(0x37D2)</td><td> L1 holds the preferred codec for CR </td><td width="100">0x01,
</td></tr>
<tr><td>SD02_PAD_OPT_NORMAL</td><td align="center">14291(0x37D3)</td><td> L1 holds the Normal action for CR: 0- nothing 1 - Mute</td><td width="100">0x00,
</td></tr>
<tr><td>SD02_PAD_OPT_PROTECTED</td><td align="center">14292(0x37D4)</td><td> L1 holds the Protected action for CR: 0- nothing 1 - Mute</td><td width="100">0x00,
</td></tr>
<tr><td>SD02_CR_ACTION_ADPCM</td><td align="center">14293(0x37D5)</td><td> L1 holds the ADPCM action for 0- nothing 1 - Improved</td><td width="100">0x00,
</td></tr>
<tr><td>SD02_CLEARANGE_ENABLE</td><td align="center">14294(0x37D6)</td><td> L1 Enable CR feature </td><td width="100">0x01,
</td></tr>
<tr><td>SD02_REPEATER_TYPE</td><td align="center">14295(0x37D7)</td><td> L1 Hold the Repeater Type GAP,CAT-iq.NEMO </td><td width="100">0x00,
</td></tr>
<tr><td>SD02_ULE_MULTICAST_ENC_PARAMS[53]</td><td align="center">14296(0x37D8)</td><td> L48 ULE Multicast enc. parameter: 2x (CCM key, sequence number, Multicast ID) </td><td width="100">0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,
0xFF,
0x0,
0x0,
0x0, 0x00,
</td></tr>
<tr><td>SD02_DECT_SETTINGS_OFFSET</td><td align="center">14349(0x380D)</td><td> DECT settings List Offset </td><td width="100"></td></tr>
<tr><td>SD02_DSSL_CLOCK_MASTER</td><td align="center">14349(0x380D)</td><td> L1 </td><td width="100"></td></tr>
<tr><td>SD02_DSSL_BASE_RESET</td><td align="center">14350(0x380E)</td><td> L1 </td><td width="100"></td></tr>
<tr><td>SD02_DSSL_FW_VERSION[38]</td><td align="center">14351(0x380F)</td><td> L8 </td><td width="100"></td></tr>
<tr><td>SD02_DSSL_EEP_VERSION[38]</td><td align="center">14389(0x3835)</td><td> L8 </td><td width="100"></td></tr>
<tr><td>SD02_DSSL_HW_VERSION[38]</td><td align="center">14427(0x385B)</td><td> L8 </td><td width="100"></td></tr>
<tr><td>SD02_DSSL_NEW_PIN[4]</td><td align="center">14465(0x3881)</td><td> L4 </td><td width="100"></td></tr>
<tr><td>SD02_DSSL_EMISSION_MODE</td><td align="center">14469(0x3885)</td><td> L1 </td><td width="100"></td></tr>
<tr><td>SD02_DSSL_IP_TYPE</td><td align="center">14470(0x3886)</td><td> L1 </td><td width="100"></td></tr>
<tr><td>SD02_DSSL_IP_VALUE[17]</td><td align="center">14471(0x3887)</td><td> L17 </td><td width="100"></td></tr>
<tr><td>SD02_DSSL_IP_SUBNET_MASK[17]</td><td align="center">14488(0x3898)</td><td> L17 </td><td width="100"></td></tr>
<tr><td>SD02_DSSL_IP_GATEWAY[17]</td><td align="center">14505(0x38A9)</td><td> L17 </td><td width="100"></td></tr>
<tr><td>SD02_DSSL_IP_DNS_SERVER[17]</td><td align="center">14522(0x38BA)</td><td> L17 </td><td width="100"></td></tr>
<tr><td>SD02_DSSL_FP_POWER_LEVEL</td><td align="center">14539(0x38CB)</td><td> L1 </td><td width="100"></td></tr>
<tr><td>SD02_LINE_SETTINGS_OFFSET[75]</td><td align="center">14540(0x38CC)</td><td> Line Settings List Offset </td><td width="100"></td></tr>
<tr><td>SD02_INL_DATA_OFFSET[375]</td><td align="center">14615(0x3917)</td><td> Internal Name List Offset </td><td width="100"></td></tr>
<tr><td>SD02_SUPTD_LIST_OFFSET[22]</td><td align="center">14990(0x3A8E)</td><td> Supported List Offset</td><td width="100"></td></tr>
<tr><td>SD02_BSNAME_LEN</td><td align="center">15012(0x3AA4)</td><td> L1 </td><td width="100"></td></tr>
<tr><td>SD02_BSNAME[19]</td><td align="center">15013(0x3AA5)</td><td> L13 Bytes of data MAX </td><td width="100"></td></tr>
<tr><td>SD02_SUB_IPUI[5]</td><td align="center">15032(0x3AB8)</td><td> L5 Data: IPUI </td><td width="100"></td></tr>
<tr><td>SD02_SUB_TPUI[3]</td><td align="center">15037(0x3ABD)</td><td> L3 Data: TPUI </td><td width="100"></td></tr>
<tr><td>SD02_SUB_DCK[16]</td><td align="center">15040(0x3AC0)</td><td> L16 Data: DCK </td><td width="100"></td></tr>
<tr><td>SD02_SUB_UAK[16]</td><td align="center">15056(0x3AD0)</td><td> L16 Data: UAK </td><td width="100"></td></tr>
<tr><td>SD02_SUB_AC[4]</td><td align="center">15072(0x3AE0)</td><td> L4 Data: authentication code AC </td><td width="100"></td></tr>
<tr><td>SD02_SUB_UAK_AUTH</td><td align="center">15076(0x3AE4)</td><td> L1 Data: UAK authorization </td><td width="100"></td></tr>
<tr><td>SD02_SUB_STATUS</td><td align="center">15077(0x3AE5)</td><td> L1 Data: status </td><td width="100"></td></tr>
<tr><td>SD02_SUB_HANDSET_NR</td><td align="center">15078(0x3AE6)</td><td> L1 Data: handset number </td><td width="100"></td></tr>
<tr><td>SD02_SUB_DCK_ASSIGNED</td><td align="center">15079(0x3AE7)</td><td> L1 Data: DCK assigned </td><td width="100"></td></tr>
<tr><td>SD02_SUB_CK_LEN</td><td align="center">15080(0x3AE8)</td><td> L1 Data: Cipher Key Length </td><td width="100"></td></tr>
<tr><td>SD02_SUB_FEATURES</td><td align="center">15081(0x3AE9)</td><td> L1 Data: Handset ULE feature support </td><td width="100"></td></tr>
<tr><td>SD02_SUB_LEN[15032]</td><td align="center">50(0x32)</td><td> End of first subscribtion </td><td width="100"></td></tr>
<tr><td>FNCA_SUB(i)[250]</td><td align="center">15082(0x3AEA)</td><td> This place is reserved for the rest of the HS and includes all perameters:SD02_SUB_IPUI-SD02_SUB_DCK_ASSIGNED (40Byte x Number of handsets)</td><td width="100"></td></tr>
<tr><td>SD02_SUB_UNUSED[6]</td><td align="center">15332(0x3BE4)</td><td> <----------- unused </td><td width="100"></td></tr>
<tr><td>SD02_SUB_EX_DEFCK[16]</td><td align="center">15338(0x3BEA)</td><td> L16 Data: Default Cipher Key </td><td width="100"></td></tr>
<tr><td>SD02_SUB_EX_DEFCK_ASSIGNED</td><td align="center">15354(0x3BFA)</td><td> L1 Data: DefCK assigned </td><td width="100"></td></tr>
<tr><td>SD02_SUB_EX_LEN[15338]</td><td align="center">17(0x11)</td><td> End of first subscribtion </td><td width="100"></td></tr>
<tr><td>FNCA_SUB_EX(i)[85]</td><td align="center">15355(0x3BFB)</td><td> This place is reserved for the rest of the HS and includes all perameters:SD02_SUB_IPUI-SD02_SUB_DCK_ASSIGNED (40Byte x Number of handsets)</td><td width="100"></td></tr>
<tr><td>SD02_SUB_EX_UNUSED[4]</td><td align="center">15440(0x3C50)</td><td> <----------- unused </td><td width="100"></td></tr>
<tr><td>SD02_SUB_RFPI</td><td align="center">15444(0x3C54)</td><td> L5 RFPI </td><td width="100"></td></tr>
</tbody>
</table>
<h3>EEPROM SIZE = 32768</h3>
<h6>*All non exists values on default are zero upon EEPROM reset</h6>

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,27 @@
#!/bin/sh
SOUND_BASE=/lib/modules/$(uname -r)/kernel/sound
SOUND_MODULES="$SOUND_BASE/soundcore.ko $SOUND_BASE/core/snd.ko $SOUND_BASE/core/snd-timer.ko"
SOUND_MODULES="$SOUND_MODULES $SOUND_BASE/core/snd-pcm.ko $SOUND_BASE/core/snd-hwdep.ko"
SOUND_MODULES="$SOUND_MODULES $SOUND_BASE/core/seq/snd-seq-device.ko"
SOUND_MODULES="$SOUND_MODULES $SOUND_BASE/core/seq/snd-seq.ko $SOUND_BASE/core/snd-rawmidi.ko "
SOUND_MODULES="$SOUND_MODULES $SOUND_BASE/usb/snd-usbmidi-lib.ko $SOUND_BASE/usb/snd-usb-audio.ko"
load_sound_modules() {
for mod in $SOUND_MODULES; do
insmod $mod
done
}
unload_sound_modules() {
local modules=
# reverse the order
for mod in $SOUND_MODULES; do
modules="$mod $modules"
done
for mod in $modules; do
rmmod $mod
done
}

308
dectmngr/src/LICENSE Normal file
View File

@@ -0,0 +1,308 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
dspg_test_app - DSPG CMBS Host Software Test Application
Copyright (C) 2020 iopsys Software Solutions AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

4
dectmngr/src/Makefile Normal file
View File

@@ -0,0 +1,4 @@
.PHONY: dectmngr
dectmngr:
$(MAKE) -C app

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,192 @@
/*************************************************************************************************************
*** List Access Session Manager
**
**************************************************************************************************************/
#ifndef __LA_SESSION_MGR_H__
#define __LA_SESSION_MGR_H__
/*******************************************
Includes
********************************************/
#include "cmbs_api.h"
#include "appcall.h"
#include "ListsApp.h"
/*******************************************
Defines
********************************************/
#define LA_SESSION_MGR_MAX_DATA_LEN 2000
#define LA_INVALID_ENTRY_ID 0xFF
/*******************************************
Types
********************************************/
typedef struct
{
u32 u32_LineId;
u32 u32_NumOfCallsBefore;
u32 u32_NumOfCallsAfter;
}stMissedCallNotifAux;
typedef struct
{
u32 u32_SMSId;
u32 u32_NumOfSMSBefore;
u32 u32_NumOfSMSAfter;
}stSMSNotifAux;
typedef struct
{
u32 u32_LineId;
u32 u32_AttachedHandsets;
}stLineDiagnosticsNotifAux;
typedef struct
{
u32 u32_HsId;
u32 u32_SessionId;
u32 u32_SaveEntryId;
u32 u32_WriteEntryId;
/* CAT-iq numbering */
u32 u32_CATiqListId;
u32 u32_CATiqSortField1;
u32 u32_CATiqSortField2;
/* CMBS Application numbering */
u32 u32_ListId;
u32 u32_SortField1;
u32 u32_SortField2;
/* Buffer for send / receive */
u8 pu8_DataBuffer[LA_SESSION_MGR_MAX_DATA_LEN];
u16 u16_DataBytesMarker;
u16 u16_DataTotalLen;
/* Auxiliary for Missed Call Notification */
stMissedCallNotifAux pst_MissedCallNotifAux[APPCALL_LINEOBJ_MAX];
/* Auxiliary for deletion of entries - List change notification */
u32 pu32_LineIdsOfDeletedEntries[APPCALL_LINEOBJ_MAX];
u32 pu32_AttachedHsOfDeletedEntries[APPCALL_LINEOBJ_MAX];
u32 u32_LineIdsSize;
/* Auxiliary for SMSl Notification */
stSMSNotifAux pst_SMSNotifAux[APPCALL_LINEOBJ_MAX];
/* Auxiliary for Line and Diagnostics */
stLineDiagnosticsNotifAux st_LineDiagNotifAux;
/* Auxiliary for Contact number field requested instance */
u8 u8_ContactNumReqInst;
u8 u8_ContactNumSaveInst;
/* Auxiliary for Read */
u8 u8_ReadInProgress;
u8 u8_OverLap;
}stLASession;
typedef enum
{
LA_SESSION_MGR_RC_OK,
LA_SESSION_MGR_RC_FAIL,
LA_SESSION_MGR_RC_NO_FREE_SESSIONS,
LA_SESSION_MGR_RC_UNSUPPORTED_LIST,
LA_SESSION_MGR_RC_UNKNOWN_SESSION_ID,
LA_SESSION_MGR_RC_NOT_ENOUGH_MEMORY,
LA_SESSION_MGR_RC_NOT_ALLOWED,
LA_SESSION_MGR_RC_INVALID_START_INDEX,
LA_SESSION_MGR_RC_ENTRY_NOT_AVAILABLE
}LA_SESSION_MGR_RC;
/*******************************************
Globals
********************************************/
/*******************************************
Session Mgr API
********************************************/
/* Init */
LA_SESSION_MGR_RC LASessionMgr_Init(void);
/* Get Data Buffer */
LA_SESSION_MGR_RC LASessionMgr_GetDataBuffer(IN u16 u16_SessionId, OUT u8** ppu8_DataBuffer, OUT u16** ppu16_Marker, OUT u16** ppu16_Len);
/* Start session */
LA_SESSION_MGR_RC LASessionMgr_StartSession(IN u16 u16_SessionId, IN u16 u16_ListId, IN u16 u16_HsId, IN PST_IE_LA_FIELDS pst_SortFields,
OUT u16* pu16_CurrNumOfEntries);
/* End Session */
LA_SESSION_MGR_RC LASessionMgr_EndSession(IN u16 u16_SessionId);
/* Get Supported Fields */
LA_SESSION_MGR_RC LASessionMgr_GetSupportedFields(IN u16 u16_SessionId,
OUT PST_IE_LA_FIELDS pst_EditableFields, OUT PST_IE_LA_FIELDS pst_NonEditableFields);
/* Read Entries */
LA_SESSION_MGR_RC LASessionMgr_ReadEntries(IN u16 u16_SessionId, INOUT u16* pu16_StartIdx, IN bool bForward, IN E_CMBS_MARK_REQUEST eMark,
IN PST_IE_LA_FIELDS pst_RequestedFields, INOUT u16* pu16_NumOfReqEntries,
OUT u8 pu8_Data[], INOUT u16* pu16_DataLen);
/* Edit Entry */
LA_SESSION_MGR_RC LASessionMgr_EditEntry(IN u16 u16_SessionId, IN u32 u32_EntryId,
IN PST_IE_LA_FIELDS pst_RequestedFields, OUT u8 pu8_Data[], INOUT u16* pu16_DataLen);
/* Search Entries */
LA_SESSION_MGR_RC LASessionMgr_SearchEntries(IN u16 u16_SessionId, IN E_CMBS_LA_SEARCH_MATCHING eMatch, IN bool bCaseSensitive,
IN const char* s_SearchedValue, IN bool bForward, IN E_CMBS_MARK_REQUEST eMark,
IN PST_IE_LA_FIELDS pst_RequestedFields, INOUT u16* pu16_NumOfReqEntries,
OUT u8 pu8_Data[], INOUT u16* pu16_DataLen, OUT u32* pu32_StartIdx);
/* Save Entry */
u32 LASessionMgr_GetSaveEntryID(IN u16 u16_SessionId);
LA_SESSION_MGR_RC LASessionMgr_SetSaveEntryID(IN u16 u16_SessionId, IN u32 u32_EntryId);
LA_SESSION_MGR_RC LASessionMgr_SaveEntry(IN u16 u16_SessionId, OUT u32* pu32_EntryId, OUT u32* pu32_PositionIdx, OUT u32* pu32_TotalNumEntries);
/* Delete Entry */
LA_SESSION_MGR_RC LASessionMgr_DeleteEntry(IN u16 u16_SessionId, IN u16 u16_EntryId, OUT u16* pu16_NumOfEntries);
/* Delete All Entries */
LA_SESSION_MGR_RC LASessionMgr_DeleteAllEntries(IN u16 u16_SessionId);
/* Send Missed call notification if needed */
LA_SESSION_MGR_RC LASessionMgr_SendMissedCallNotification(IN u16 u16_SessionId, IN E_CMBS_MARK_REQUEST eMark);
/* Send list changed notification if needed */
LA_SESSION_MGR_RC LASessionMgr_SendListChangedNotification(IN u16 u16_SessionId, IN u16 u16_EntryId);
LA_SESSION_MGR_RC LASessionMgr_SendListChangedNotificationOnDelete(IN u16 u16_SessionId);
LA_SESSION_MGR_RC LASessionMgr_SendSMSNotification(IN u16 u16_SessionId, IN E_CMBS_MARK_REQUEST eMark);
u8 LASessionMgr_GetReadInProgress(IN u16 u16_SessionId);
LA_SESSION_MGR_RC LASessionMgr_SetReadInProgress(IN u16 u16_SessionId, IN u8 u8_ReadInProgress);
u8 LASessionMgr_GetOverLap(IN u16 u16_SessionId);
LA_SESSION_MGR_RC LASessionMgr_SetOverLap(IN u16 u16_SessionId, IN u8 u8_OverLap);
/* Write Entry */
u32 LASessionMgr_GetWriteEntryID(IN u16 u16_SessionId);
LA_SESSION_MGR_RC LASessionMgr_SetWriteEntryID(IN u16 u16_SessionId, IN u32 u32_EntryId);
/* retrieve entry ID from LineSettingsList */
u32 LineSettingsGetEntryIdByLineId(int lineID);
/* retrieve entry ID from Line and Diagnostic Status List */
u32 LineDiagnosticGetEntryIdByLineId(int lineID);
/* retrieve SMS ID from SMS List */
u32 GetSMSIdByEntryId(IN u32 u32_EntryId, IN LIST_TYPE ListType);
/* retrieve Line ID from SMS List */
E_CMBS_RC GetLineIdBySMSId(IN u32 u32_SMSId, OUT u32* pu32_LineId);
/* retrieve SMS ID from SMS List */
E_CMBS_RC GetSMSIdByLineID(IN u32 u32_LineId, OUT u32* pu32_SMSId);
/* retrieve Contact name from contact list using number */
E_CMBS_RC GetContactNameByNumber(IN char * psz_Number, OUT char * psz_Name, OUT char * psz_FName);
#endif /* __LA_SESSION_MGR_H__ */
/* End Of File *****************************************************************************************************************************/

View File

@@ -0,0 +1,27 @@
ifdef CMBSDIR
LISTACCESSBASE:=$(CMBSDIR)/app/ListAccess
else
LISTACCESSBASE:=$(BASE)/ListAccess
endif
####################################################################
# settle includes
includes += -I$(LISTACCESSBASE)
####################################################################
# settle objects
objects += $(OBJDIR)/sqlite3.o
objects += $(OBJDIR)/SQLiteWrapper.o
objects += $(OBJDIR)/ListsApp.o
objects += $(OBJDIR)/LASessionMgr.o
objects += $(OBJDIR)/ListChangeNotif.o
####################################################################
# Libraries
ifeq ($(HOST_OS),UNIX)
LIBS += -ldl
endif
####################################################################
# settle vpath
vpath %.c $(LISTACCESSBASE)

View File

@@ -0,0 +1,335 @@
/*************************************************************************************************************
*** List Change Notification
**
**************************************************************************************************************/
/*******************************************
Includes
********************************************/
#include "ListChangeNotif.h"
#include "cfr_mssg.h"
#include "appcmbs.h"
#include "ListsApp.h"
#include "appsrv.h"
#include "appfacility.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*******************************************
Defines
********************************************/
/*******************************************
Types
********************************************/
/*******************************************
Globals
********************************************/
static u8 s_u8_AggregateFaciltiy = 0;
/*******************************************
Auxiliary
********************************************/
extern E_CMBS_RC GetLineIdBySMSId(IN u32 u32_SMSId, OUT u32 *pu32_LineId);
/* ***************** Auxiliary end ***************** */
/*******************************************
List Change Notification API
u16_HsId may be a single HS ID or all handsets which are attached to the given line (CMBS_ALL_RELEVANT_HS_ID)
********************************************/
void ListChangeNotif_MissedCallListChanged(IN u32 u32_LineId, IN bool bNewEntryAdded, IN u16 u16_HsId)
{
u32 u32_HandsetMask = 0, u32_NumOfRead = 0, u32_NumOfUnread = 0;
LIST_RC rc;
APP_FACILITY_INFO_PRINT("ListChangeNotif_MissedCallListChanged LineID %d u16_HsId %d \n",u32_LineId, u16_HsId);
rc = List_GetAttachedHs(u32_LineId, &u32_HandsetMask);
if(rc == LIST_RC_OK)
{
APP_FACILITY_INFO_PRINT("ListChangeNotif_MissedCallListChanged u32_HandsetMask1 %x \n", u32_HandsetMask);
// if only one HS has to be notified, mask other handsets:
if ( u16_HsId != CMBS_ALL_RELEVANT_HS_ID )
{
u32_HandsetMask &= (1 << (u16_HsId - 1));
}
APP_FACILITY_INFO_PRINT("ListChangeNotif_MissedCallListChanged u32_HandsetMask2 %x \n", u32_HandsetMask);
if ( u32_HandsetMask )
{
List_GetMissedCallsNumOfEntries(u32_LineId, &u32_NumOfUnread, &u32_NumOfRead);
app_FacilityMissedCalls(0, (u8)u32_LineId, (u16)u32_NumOfUnread, (u16)u32_HandsetMask, bNewEntryAdded, (u16)(u32_NumOfUnread + u32_NumOfRead));
}
}
else
APP_FACILITY_ERROR_PRINT("List_GetAttachedHs failed \n");
}
void ListChangeNotif_ListChanged(IN u32 u32_LineId, IN eLineType tLineType, IN u32 u32_HandsetMask,
IN u32 u32_TotalNumOfEntries, IN eLIST_CHANGE_NOTIF_LIST_TYPE tListId)
{
app_FacilityListChanged(0, tListId, (u8)u32_TotalNumOfEntries, (u16)u32_HandsetMask, (u8)u32_LineId, tLineType);
}
void ListChangeNotif_OutgoingCallListChangedEx(IN u32 u32_LineId, IN bool bNewEntryAdded, IN u16 u16_HsId)
{
u32 u32_HandsetMask = 0, u32_NumOfEntries = 0;
LIST_RC rc;
ST_APP_FACILITY_LCN_DETAILS st_Details;
APP_FACILITY_INFO_PRINT("ListChangeNotif_OutgoingCallListChangedEx LineID %d u16_HsId %d \n",u32_LineId, u16_HsId);
rc = List_GetAttachedHs(u32_LineId, &u32_HandsetMask);
if(rc == LIST_RC_OK)
{
APP_FACILITY_INFO_PRINT("ListChangeNotif_OutgoingCallListChangedEx u32_HandsetMask1 %x \n", u32_HandsetMask);
if ( u32_HandsetMask )
{
List_GetOutgoingCallsNumOfEntries(u32_LineId, &u32_NumOfEntries);
st_Details.u8_Count = 1; // one change
st_Details.u16_OrgHs = u16_HsId; //HS num from which outgoing call is made
st_Details.st_SubDetails[0].u16_Change = 1; //Add
st_Details.st_SubDetails[0].u16_EntryId = 1; //last outgoing call will have entry id 1
st_Details.st_SubDetails[0].u16_PosIndex = u32_NumOfEntries-1; // considering last outgoing call is added to the end of list.
app_FacilityListChangedEx(0, LIST_CHANGE_NOTIF_LIST_TYPE_OUTGOING_CALLS, u32_NumOfEntries,
(u16)u32_HandsetMask, u32_LineId, LINE_TYPE_EXTERNAL, &st_Details);
}
}
else
APP_FACILITY_ERROR_PRINT("List_GetAttachedHs failed \n");
}
void ListChangeNotif_SMSListChanged(IN u32 u32_SMSId, IN u8 ListType, IN u16 u16_HsId)
{
u32 u32_HandsetMask = 0, u32_TotalNumOfEntries = 0, u32_LineId = 0;
eLIST_CHANGE_NOTIF_LIST_TYPE tListId = 0;
LIST_RC rc;
if ( GetLineIdBySMSId(u32_SMSId, &u32_LineId) == CMBS_RC_OK )
{
if(List_GetAttachedHs(u32_LineId, &u32_HandsetMask) == LIST_RC_OK)
{
rc = List_GetCount(ListType, &u32_TotalNumOfEntries);
if ( rc != LIST_RC_OK )
APP_FACILITY_ERROR_PRINT("List_GetCount failed!\n");
if ( u16_HsId != CMBS_ALL_RELEVANT_HS_ID )
{
u32_HandsetMask &= (1 << (u16_HsId - 1));
}
switch ((LIST_TYPE)ListType)
{
case LIST_TYPE_INCOMING_SMS:
tListId = LIST_CHANGE_NOTIF_LIST_TYPE_INCOMING_SMS; break;
case LIST_TYPE_SENT_SMS:
tListId = LIST_CHANGE_NOTIF_LIST_TYPE_SENT_SMS; break;
case LIST_TYPE_OUTGOING_SMS:
tListId = LIST_CHANGE_NOTIF_LIST_TYPE_OUTGOING_SMS; break;
case LIST_TYPE_DRAFT_SMS:
tListId = LIST_CHANGE_NOTIF_LIST_TYPE_DRAFT_SMS; break;
default:
APP_FACILITY_WARNING_PRINT("Not SMS list, aborting");
return;
}
app_FacilityListChanged(0, tListId, (u8)u32_TotalNumOfEntries, (u16)u32_HandsetMask, (u8)u32_LineId, 0);
}
else
APP_FACILITY_ERROR_PRINT("List_GetAttachedHs failed \n");
}
else
{
APP_FACILITY_ERROR_PRINT("GetLineIdBySMSId failed!\n");
}
}
void ListChangeNotif_IncomingSMSListChanged(IN u32 u32_SMSId, IN u8 u8_SMSType, IN u16 u16_HsId)
{
u32 u32_NumOfRead, u32_NumOfUnread, u32_HandsetMask, u32_LineId;
if ( GetLineIdBySMSId(u32_SMSId, &u32_LineId) == CMBS_RC_OK )
{
if(List_GetAttachedHs(u32_LineId, &u32_HandsetMask) == LIST_RC_OK)
{
APP_FACILITY_INFO_PRINT("ListChangeNotif_IncomingSMSListChanged \n");
if ( u16_HsId != CMBS_ALL_RELEVANT_HS_ID )
{
u32_HandsetMask &= (1 << (u16_HsId - 1));
}
List_GetSMSNumOfEntries(u32_SMSId, &u32_NumOfUnread, &u32_NumOfRead);
app_FacilitySMSMessageNotification(u8_SMSType, (u16)(u32_NumOfUnread + u32_NumOfRead), (u16)u32_NumOfUnread, u32_HandsetMask);
}
else
APP_FACILITY_ERROR_PRINT("List_GetAttachedHs failed! \n");
}
else
{
APP_FACILITY_ERROR_PRINT("GetLineIdBySMSId failed!\n");
}
}
void ListChangeNotif_SendListChangeDetails( IN u8 ListType)
{
LIST_RC rc = LIST_RC_OK;
ST_APP_FACILITY_LCN_DETAILS *pst_LcnDetails = NULL;
if (List_GetListChangeDetails(ListType, &pst_LcnDetails) == LIST_RC_OK)
{
eLIST_CHANGE_NOTIF_LIST_TYPE tListId = 0;
u32 u32_Count;
switch ((LIST_TYPE)ListType)
{
case LIST_TYPE_CONTACT_LIST:
tListId = LIST_CHANGE_NOTIF_LIST_TYPE_CONTACT_LIST; break;
case LIST_TYPE_LINE_SETTINGS_LIST:
tListId = LIST_CHANGE_NOTIF_LIST_TYPE_LINE_SETTINGS_LIST; break;
case LIST_TYPE_MISSED_CALLS :
tListId = LIST_CHANGE_NOTIF_LIST_TYPE_MISSED_CALLS; break;
case LIST_TYPE_OUTGOING_CALLS :
tListId = LIST_CHANGE_NOTIF_LIST_TYPE_OUTGOING_CALLS; break;
case LIST_TYPE_INCOMING_ACCEPTED_CALLS :
tListId = LIST_CHANGE_NOTIF_LIST_TYPE_INCOMING_ACCEPTED_CALLS; break;
case LIST_TYPE_ALL_CALLS :
tListId = LIST_CHANGE_NOTIF_LIST_TYPE_ALL_CALLS; break;
case LIST_TYPE_ALL_INCOMING_CALLS:
tListId = LIST_CHANGE_NOTIF_LIST_TYPE_ALL_INCOMING_CALLS; break;
case LIST_TYPE_INCOMING_SMS:
tListId = LIST_CHANGE_NOTIF_LIST_TYPE_INCOMING_SMS; break;
case LIST_TYPE_SENT_SMS:
tListId = LIST_CHANGE_NOTIF_LIST_TYPE_SENT_SMS; break;
case LIST_TYPE_OUTGOING_SMS:
tListId = LIST_CHANGE_NOTIF_LIST_TYPE_OUTGOING_SMS; break;
case LIST_TYPE_DRAFT_SMS:
tListId = LIST_CHANGE_NOTIF_LIST_TYPE_DRAFT_SMS; break;
case LIST_TYPE_DTAM_SETTINGS_LIST:
case LIST_TYPE_SMS_SETTINGS_LIST:
case LIST_TYPE_DTAM_WELCOME_MESSAGE:
case LIST_TYPE_LINE_AND_DIAGNOSTIC_STATUS:
default :
APP_FACILITY_WARNING_PRINT("send list change details, aborting list type %d", ListType);
return;
}
/* Get Count */
rc = List_GetCount(ListType, &u32_Count);
if ((rc != LIST_RC_OK) && (pst_LcnDetails == NULL))
{
return;
}
if ( (ListType >= LIST_TYPE_MISSED_CALLS) && (ListType <= LIST_TYPE_ALL_INCOMING_CALLS) )
{
app_FacilityListChangedEx (0, tListId, u32_Count, CMBS_ALL_HS_MASK, 0, LINE_TYPE_EXTERNAL, pst_LcnDetails);
}
else
{
app_FacilityListChangedEx (0, tListId, u32_Count, CMBS_ALL_HS_MASK, 0, LINE_TYPE_ALL_LINES, pst_LcnDetails);
}
}
List_ResetListChangeDetails (ListType);
}
void ListChangeNotif_SendAllListChangeDetails( void )
{
LIST_TYPE ListType = 0;
while (ListType < LIST_TYPE_MAX)
{
ListChangeNotif_SendListChangeDetails(ListType);
ListType++;
}
}
void ListChangeNotif_SendListChangeDetailsEx( IN u8 ListType, IN u8 u8_LineId, IN u8 u8_LineSubtype)
{
LIST_RC rc = LIST_RC_OK;
ST_APP_FACILITY_LCN_DETAILS *pst_LcnDetails = NULL;
if (s_u8_AggregateFaciltiy)
{
/* Send Facility with later */
return;
}
if (List_GetListChangeDetails(ListType, &pst_LcnDetails) == LIST_RC_OK)
{
eLIST_CHANGE_NOTIF_LIST_TYPE tListId = 0;
u32 u32_Count;
switch ((LIST_TYPE)ListType)
{
case LIST_TYPE_CONTACT_LIST:
tListId = LIST_CHANGE_NOTIF_LIST_TYPE_CONTACT_LIST; break;
case LIST_TYPE_LINE_SETTINGS_LIST:
tListId = LIST_CHANGE_NOTIF_LIST_TYPE_LINE_SETTINGS_LIST; break;
case LIST_TYPE_MISSED_CALLS :
tListId = LIST_CHANGE_NOTIF_LIST_TYPE_MISSED_CALLS; break;
case LIST_TYPE_OUTGOING_CALLS :
tListId = LIST_CHANGE_NOTIF_LIST_TYPE_OUTGOING_CALLS; break;
case LIST_TYPE_INCOMING_ACCEPTED_CALLS :
tListId = LIST_CHANGE_NOTIF_LIST_TYPE_INCOMING_ACCEPTED_CALLS; break;
case LIST_TYPE_ALL_CALLS :
tListId = LIST_CHANGE_NOTIF_LIST_TYPE_ALL_CALLS; break;
case LIST_TYPE_ALL_INCOMING_CALLS:
tListId = LIST_CHANGE_NOTIF_LIST_TYPE_ALL_INCOMING_CALLS; break;
case LIST_TYPE_INCOMING_SMS:
tListId = LIST_CHANGE_NOTIF_LIST_TYPE_INCOMING_SMS; break;
case LIST_TYPE_SENT_SMS:
tListId = LIST_CHANGE_NOTIF_LIST_TYPE_SENT_SMS; break;
case LIST_TYPE_OUTGOING_SMS:
tListId = LIST_CHANGE_NOTIF_LIST_TYPE_OUTGOING_SMS; break;
case LIST_TYPE_DRAFT_SMS:
tListId = LIST_CHANGE_NOTIF_LIST_TYPE_DRAFT_SMS; break;
case LIST_TYPE_DTAM_SETTINGS_LIST:
case LIST_TYPE_SMS_SETTINGS_LIST:
case LIST_TYPE_DTAM_WELCOME_MESSAGE:
case LIST_TYPE_LINE_AND_DIAGNOSTIC_STATUS:
default :
APP_FACILITY_WARNING_PRINT("send list change details, aborting list type %d", ListType);
return;
}
/* Get Count */
rc = List_GetCount(ListType, &u32_Count);
if ((rc != LIST_RC_OK) && (pst_LcnDetails == NULL))
{
return;
}
app_FacilityListChangedEx (0, tListId, u32_Count, CMBS_ALL_HS_MASK, u8_LineId, u8_LineSubtype, pst_LcnDetails);
}
List_ResetListChangeDetails (ListType);
}
void ListChangeNotif_AggregateListChangeDetails( IN u8 u8_AggregateFaciltiy )
{
s_u8_AggregateFaciltiy = u8_AggregateFaciltiy;
}
/* End Of File *****************************************************************************************************************************/

View File

@@ -0,0 +1,76 @@
/*************************************************************************************************************
*** List Change Notification
**
**************************************************************************************************************/
#ifndef __LA_LIST_CHANGE_NOTIF_H__
#define __LA_LIST_CHANGE_NOTIF_H__
/*******************************************
Includes
********************************************/
#include "cmbs_api.h"
/*******************************************
Defines
********************************************/
/*******************************************
Types
********************************************/
typedef enum
{
LINE_TYPE_EXTERNAL = 0x00,
LINE_TYPE_RELATING_TO = 0x03,
LINE_TYPE_ALL_LINES = 0x04
} eLineType;
typedef enum
{
LIST_CHANGE_NOTIF_LIST_TYPE_MISSED_CALLS = 1,
LIST_CHANGE_NOTIF_LIST_TYPE_OUTGOING_CALLS,
LIST_CHANGE_NOTIF_LIST_TYPE_INCOMING_ACCEPTED_CALLS,
LIST_CHANGE_NOTIF_LIST_TYPE_ALL_CALLS,
LIST_CHANGE_NOTIF_LIST_TYPE_CONTACT_LIST,
LIST_CHANGE_NOTIF_LIST_TYPE_INTERNAL_NAMES_LIST,
LIST_CHANGE_NOTIF_LIST_TYPE_DECT_SETTINGS_LIST,
LIST_CHANGE_NOTIF_LIST_TYPE_LINE_SETTINGS_LIST,
LIST_CHANGE_NOTIF_LIST_TYPE_ALL_INCOMING_CALLS,
LIST_CHANGE_NOTIF_LIST_TYPE_INCOMING_SMS = 12,
LIST_CHANGE_NOTIF_LIST_TYPE_SENT_SMS = 13,
LIST_CHANGE_NOTIF_LIST_TYPE_OUTGOING_SMS = 14,
LIST_CHANGE_NOTIF_LIST_TYPE_DRAFT_SMS = 15,
LIST_CHANGE_NOTIF_LIST_TYPE_MAX
}eLIST_CHANGE_NOTIF_LIST_TYPE;
/*******************************************
Globals
********************************************/
/*******************************************
List Change Notification API
********************************************/
void ListChangeNotif_MissedCallListChanged( IN u32 u32_LineId, IN bool bNewEntryAdded, IN u16 u16_HsId );
void ListChangeNotif_ListChanged( IN u32 u32_LineId, IN eLineType tLineType, IN u32 u32_HandsetMask,
IN u32 u32_TotalNumOfEntries, IN eLIST_CHANGE_NOTIF_LIST_TYPE tListId );
void ListChangeNotif_SMSListChanged(IN u32 u32_SMSId, IN u8 ListType, IN u16 u16_HsId);
void ListChangeNotif_IncomingSMSListChanged( IN u32 u32_SMSId, IN u8 u8_SMSType, IN u16 u16_HsId );
void ListChangeNotif_SendListChangeDetails( IN u8 ListType);
void ListChangeNotif_SendAllListChangeDetails( void );
void ListChangeNotif_SendListChangeDetailsEx( IN u8 ListType, IN u8 u8_LineId, IN u8 u8_LineSubtype);
void ListChangeNotif_AggregateListChangeDetails( IN u8 u8_AggregateFaciltiy );
#endif /* __LA_LIST_CHANGE_NOTIF_H__ */
/* End Of File *****************************************************************************************************************************/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,729 @@
/*************************************************************************************************************
*** ListsApp
*** An implementation of lists API over SQL database
**
**************************************************************************************************************/
#ifndef __LISTS_APP_H__
#define __LISTS_APP_H__
/*******************************************
Includes
********************************************/
#include "cmbs_api.h"
#include "SQLiteWrapper.h"
#include "cfr_debug.h"
#include "appfacility.h"
/*******************************************
Defines
********************************************/
#define LIST_NAME_MAX_LEN 30
#define LIST_NUMBER_MAX_LEN 30
#define LIST_LINE_ID_NONE 0xFFFF
/*******************************************
Types
********************************************/
typedef enum
{
MATCH_EXACT,
MATCH_RETURN_NEXT_ON_FAIL,
MATCH_RETURN_PREV_ON_FAIL
}eMatchOption;
typedef enum
{
LIST_RC_OK = 0,
LIST_RC_FAIL,
LIST_RC_UNSUPPORTED_LIST,
LIST_RC_ARRAY_TOO_SMALL,
LIST_RC_UNKNOWN_FIELD,
LIST_RC_NO_SORT,
LIST_RC_UNSUPPORTED_MATCH_OPTION,
LIST_RC_INVALID_START_INDEX,
LIST_RC_ENTRY_NOT_AVAILABLE
}LIST_RC;
typedef enum
{
LIST_TYPE_CONTACT_LIST,
LIST_TYPE_LINE_SETTINGS_LIST,
LIST_TYPE_MISSED_CALLS,
LIST_TYPE_OUTGOING_CALLS,
LIST_TYPE_INCOMING_ACCEPTED_CALLS,
LIST_TYPE_ALL_CALLS,
LIST_TYPE_ALL_INCOMING_CALLS,
LIST_TYPE_LINE_AND_DIAGNOSTIC_STATUS,
LIST_TYPE_SMS_SETTINGS_LIST,
LIST_TYPE_INCOMING_SMS,
LIST_TYPE_SENT_SMS,
LIST_TYPE_OUTGOING_SMS,
LIST_TYPE_DRAFT_SMS,
LIST_TYPE_DTAM_SETTINGS_LIST,
LIST_TYPE_DTAM_WELCOME_MESSAGE,
LIST_TYPE_MAX
}LIST_TYPE;
typedef enum
{
FIELD_TYPE_CHAR,
FIELD_TYPE_INT,
FIELD_TYPE_TEXT,
FIELD_TYPE_MAX
} FIELD_TYPE;
typedef enum
{
FIELD_ID_INVALID = -1,
FIELD_ID_ENTRY_ID,
FIELD_ID_LAST_NAME,
FIELD_ID_FIRST_NAME,
FIELD_ID_CONTACT_NUM_1,
FIELD_ID_CONTACT_NUM_1_TYPE,
FIELD_ID_CONTACT_NUM_1_OWN,
FIELD_ID_CONTACT_NUM_1_DEFAULT,
FIELD_ID_CONTACT_NUM_2,
FIELD_ID_CONTACT_NUM_2_TYPE,
FIELD_ID_CONTACT_NUM_2_OWN,
FIELD_ID_CONTACT_NUM_2_DEFAULT,
FIELD_ID_CONTACT_NUM_3,
FIELD_ID_CONTACT_NUM_3_TYPE,
FIELD_ID_CONTACT_NUM_3_OWN,
FIELD_ID_CONTACT_NUM_3_DEFAULT,
FIELD_ID_ASSOCIATED_MELODY,
FIELD_ID_LINE_ID,
FIELD_ID_NUMBER,
FIELD_ID_DATE_AND_TIME,
FIELD_ID_READ_STATUS,
FIELD_ID_LINE_NAME,
FIELD_ID_NUM_OF_CALLS,
FIELD_ID_CALL_TYPE,
FIELD_ID_ATTACHED_HANDSETS,
FIELD_ID_DIALING_PREFIX,
FIELD_ID_FP_MELODY,
FIELD_ID_FP_VOLUME,
FIELD_ID_BLOCKED_NUMBER,
FIELD_ID_MULTIPLE_CALLS_MODE,
FIELD_ID_INTRUSION_CALL,
FIELD_ID_PERMANENT_CLIR,
FIELD_ID_PERMANENT_CLIR_ACTIVATION_CODE,
FIELD_ID_PERMANENT_CLIR_DEACTIVATION_CODE,
FIELD_ID_CALL_FWD_UNCOND,
FIELD_ID_CALL_FWD_UNCOND_ACTIVATION_CODE,
FIELD_ID_CALL_FWD_UNCOND_DEACTIVATION_CODE,
FIELD_ID_CALL_FWD_UNCOND_TARGET_NUMBER,
FIELD_ID_CALL_FWD_NO_ANSWER,
FIELD_ID_CALL_FWD_NO_ANSWER_ACTIVATION_CODE,
FIELD_ID_CALL_FWD_NO_ANSWER_DEACTIVATION_CODE,
FIELD_ID_CALL_FWD_NO_ANSWER_TARGET_NUMBER,
FIELD_ID_CALL_FWD_NO_ANSWER_TIMEOUT,
FIELD_ID_CALL_FWD_BUSY,
FIELD_ID_CALL_FWD_BUSY_ACTIVATION_CODE,
FIELD_ID_CALL_FWD_BUSY_DEACTIVATION_CODE,
FIELD_ID_CALL_FWD_BUSY_TARGET_NUMBER,
FIELD_ID_OK_STATUS,
FIELD_ID_LINE_USE_STATUS,
FIELD_ID_HS_USE_STATUS,
FIELD_ID_CALL_FWD_CFU_STATUS,
FIELD_ID_CALL_FWD_CFNA_STATUS,
FIELD_ID_CALL_FWD_CFB_STATUS,
FIELD_ID_DIAGNOSTIC_ERROR_STATUS,
FIELD_ID_DIAGNOSTIC_ERROR_TYPE,
FIELD_ID_DIAGNOSTIC_ERROR_NUMBER,
FIELD_ID_DTAM_IDENTIFIER,
FIELD_ID_DTAM_TYPE,
FIELD_ID_DTAM_LOCATION,
FIELD_ID_DTAM_NUMBER,
FIELD_ID_DTAM_ACTIVATION,
FIELD_ID_DTAM_DEFAULT_TIMEOUT,
FIELD_ID_DTAM_TIMEOUT,
FIELD_ID_DTAM_WEB_LINK,
FIELD_ID_DTAM_WELCOME_MSG_PARAMETERS,
FIELD_ID_DTAM_POSITION_INDEX,
FIELD_ID_DTAM_RECORDED_MSG_NAME,
FIELD_ID_DTAM_TIME_DURATION_HOURS,
FIELD_ID_DTAM_TIME_DURATION_MINUTES,
FIELD_ID_DTAM_TIME_DURATION_SECONDS,
FIELD_ID_NAME,
FIELD_ID_SMS_IDENTIFIER,
FIELD_ID_SMS_ENABLE,
FIELD_ID_SMS_MAX_SIZE,
FIELD_ID_SMSC_SEND_SERVER,
FIELD_ID_SMSC_RECEIVE_SERVER,
FIELD_ID_SMS_DELIVERY_REPORT,
FIELD_ID_SMS_VALIDITY_PERIOD,
FIELD_ID_SMS_CHAR_ALLOWED_ENCODING,
FIELD_ID_SMS_ALLOWED_ENCODING_0,
FIELD_ID_SMS_ALLOWED_ENCODING_1,
FIELD_ID_SMS_ALLOWED_ENCODING_2,
FIELD_ID_SMS_ALLOWED_ENCODING_3,
FIELD_ID_SMS_ALLOWED_ENCODING_4,
FIELD_ID_SMS_ALLOWED_ENCODING_5,
FIELD_ID_SMS_ALLOWED_ENCODING_6,
FIELD_ID_SMS_ALLOWED_ENCODING_7,
FIELD_ID_SMS_ALLOWED_ENCODING_8,
FIELD_ID_SMS_ALLOWED_ENCODING_9,
FIELD_ID_SMS_ALLOWED_ENCODING_10,
FIELD_ID_SMS_ALLOWED_ENCODING_11,
FIELD_ID_SMS_ALLOWED_ENCODING_12,
FIELD_ID_SMS_ALLOWED_ENCODING_13,
FIELD_ID_SMS_ALLOWED_ENCODING_14,
FIELD_ID_SMS_CHAR_ALLOWED_ENCODING_2,
FIELD_ID_SMS_CHAR_ALLOWED_ENCODING_3,
FIELD_ID_SMS_CHAR_ALLOWED_ENCODING_4,
FIELD_ID_SMS_NETWORK_ENCODING,
FIELD_ID_SMS_ENCODING_VARIANT_1,
FIELD_ID_SMS_ENCODING_VARIANT_2,
FIELD_ID_SMS_SEND_REQUEST,
FIELD_ID_SMS_SIZE,
FIELD_ID_SMS_CONTENT,
FIELD_ID_SMS_TYPE,
FIELD_ID_MAX
} FIELD_ID;
typedef struct
{
const char* s_Name;
FIELD_TYPE e_Type;
bool b_AutoInc;
bool b_PrimaryKey;
bool b_Mandatory;
bool b_Editable;
FIELD_ID e_FieldId;
}stListField;
typedef enum
{
NUM_TYPE_FIXED,
NUM_TYPE_MOBILE,
NUM_TYPE_WORK
}eNumberType;
typedef struct
{
u32 u32_EntryId;
char sLastName[LIST_NAME_MAX_LEN];
char sFirstName[LIST_NAME_MAX_LEN];
char sNumber1[LIST_NUMBER_MAX_LEN];
char cNumber1Type;
bool bNumber1Default;
bool bNumber1Own;
char sNumber2[LIST_NUMBER_MAX_LEN];
char cNumber2Type;
bool bNumber2Default;
bool bNumber2Own;
char sNumber3[LIST_NUMBER_MAX_LEN];
char cNumber3Type;
bool bNumber3Default;
bool bNumber3Own;
u32 u32_AssociatedMelody;
u32 u32_LineId;
}stContactListEntry;
typedef enum
{
CALL_TYPE_MISSED,
CALL_TYPE_OUTGOING,
CALL_TYPE_INCOMING
}eCallType;
typedef enum
{
SMS_TYPE_INCOMING,
SMS_TYPE_OUTGOING,
SMS_TYPE_DRAFT,
SMS_TYPE_SENT
}eSMSType;
typedef struct
{
u32 u32_EntryId;
char sNumber[LIST_NUMBER_MAX_LEN];
time_t t_DateAndTime;
bool bRead;
char sLineName[LIST_NAME_MAX_LEN]; /* Stored in LineSettingsList */
u32 u32_LineId;
u32 u32_NumOfCalls;
char cCallType;
char sLastName[LIST_NAME_MAX_LEN]; /* stored in ContactList */
char sFirstName[LIST_NAME_MAX_LEN]; /* stored in ContactList */
}stCallsListEntry;
typedef struct
{
u32 u32_EntryId;
char sLineName[LIST_NAME_MAX_LEN];
u32 u32_LineId;
u32 u32_AttachedHsMask;
char sDialPrefix[LIST_NUMBER_MAX_LEN];
u32 u32_FPMelody;
u32 u32_FPVolume;
char sBlockedNumber[LIST_NUMBER_MAX_LEN];
bool bMultiCalls;
bool bIntrusionCall;
bool bPermanentCLIR;
char sPermanentCLIRActCode[LIST_NUMBER_MAX_LEN];
char sPermanentCLIRDeactCode[LIST_NUMBER_MAX_LEN];
bool bCallFwdUncond;
char sCallFwdUncondActCode[LIST_NUMBER_MAX_LEN];
char sCallFwdUncondDeactCode[LIST_NUMBER_MAX_LEN];
char sCallFwdUncondNum[LIST_NUMBER_MAX_LEN];
bool bCallFwdNoAns;
char sCallFwdNoAnsActCode[LIST_NUMBER_MAX_LEN];
char sCallFwdNoAnsDeactCode[LIST_NUMBER_MAX_LEN];
char sCallFwdNoAnsNum[LIST_NUMBER_MAX_LEN];
u32 u32_CallFwdNoAnsTimeout;
bool bCallFwdBusy;
char sCallFwdBusyActCode[LIST_NUMBER_MAX_LEN];
char sCallFwdBusyDeactCode[LIST_NUMBER_MAX_LEN];
char sCallFwdBusyNum[LIST_NUMBER_MAX_LEN];
}stLineSettingsListEntry;
typedef struct
{
u32 u32_EntryId;
u32 u32_LineId;
u32 u32_OKStatus;
u32 u32_LineUseStatus;
u32 u32_HSUseStatus;
bool b_CallFwdUncondStatus;
bool b_CallFwdNoAnswerStatus;
bool b_CallFwdBusyStatus;
bool b_DiagnosticErrorStatus;
u32 u32_DiagnosticErrorType;
u32 u32_DiagnosticErrorNumber;
}stLineAndDiagnosticListEntry;
typedef struct
{
u32 u32_EntryId;
u32 u32_LineId;
u32 u32_DTAMIdentifier;
bool b_DTAMType;
bool b_DTAMLocation;
char sDTAMNumber[LIST_NUMBER_MAX_LEN];
bool b_DTAMActivation;
bool b_DTAMDefaultTimeout;
u32 u32_DTAMTimeout;
char sDTAMWebLink[LIST_NUMBER_MAX_LEN];
u32 u32_WelcomeMsgParams;
}stDTAMSettingsListEntry;
typedef struct
{
u32 u32_EntryId;
u32 u32_DTAMIdentifier;
bool b_DTAMType;
bool b_DTAMLocation;
u32 u32_PositionIdx;
char sRecordedMsgName[LIST_NAME_MAX_LEN];
u32 u32_TimeDurationHours;
u32 u32_TimeDurationMinutes;
u32 u32_TimeDurationSeconds;
}stDTAMWelcomeMessageListEntry;
typedef struct
{
u32 u32_EntryId;
u32 u32_SMSServiseId;
u32 u32_LineId;
bool b_EnableSMS;
u32 u32_SMSMaxSize;
char sSMSCSendServer[LIST_NUMBER_MAX_LEN];
char sSMSCReceiveServer[LIST_NUMBER_MAX_LEN];
bool b_SMSDeliveryReport;
u32 u32_SMSValidityPeriod;
u32 u32_LengthOfAllowedEncoding_1;
u32 u32_SMSCharacterEncodingValue_1;
u32 u32_AllowedEncoding_0;
u32 u32_AllowedEncoding_1;
u32 u32_AllowedEncoding_2;
u32 u32_AllowedEncoding_3;
u32 u32_AllowedEncoding_4;
u32 u32_AllowedEncoding_5;
u32 u32_AllowedEncoding_6;
u32 u32_AllowedEncoding_7;
u32 u32_AllowedEncoding_8;
u32 u32_AllowedEncoding_9;
u32 u32_AllowedEncoding_10;
u32 u32_AllowedEncoding_11;
u32 u32_AllowedEncoding_12;
u32 u32_AllowedEncoding_13;
u32 u32_AllowedEncoding_14;
u32 u32_LengthOfAllowedEncoding_2;
u32 u32_SMSCharacterEncodingValue_2;
u32 u32_LengthOfAllowedEncoding_3;
u32 u32_SMSCharacterEncodingValue_3;
u32 u32_LengthOfAllowedEncoding_4;
u32 u32_SMSCharacterEncodingValue_4;
}stSMSSettingsListEntry;
#define LIST_MAX_SMS_SIZE 100
typedef struct
{
u32 u32_EntryId;
char sNumber[LIST_NUMBER_MAX_LEN];
char sName[LIST_NUMBER_MAX_LEN];
time_t t_DateAndTime;
bool b_Read;
bool b_SendRequest;
u32 u32_SMSServiseId;
u32 u32_NetworkSideEncoding;
u32 u32_EncVariant_1;
u32 u32_EncVariant_2;
u32 u32_SMSSize;
char sSMSContent[LIST_MAX_SMS_SIZE];
char cSMSType;
}stSMSListEntry;
typedef struct
{
bool b_Default; //0x0
bool b_Turkish; //0x1
bool b_Spanish; //0x2
bool b_Portuguese; //0x3
bool b_Bengali; //0x4
bool b_Gujarati; //0x5
bool b_Hindi; //0x6
bool b_Kannada; //0x7
bool b_Malayalam; //0x8
bool b_Oriya; //0x9
bool b_Punjabi; //0x10
bool b_Tamil; //0x11
bool b_Telugu; //0x12
bool b_Urdu; //0x13
bool b_Reserved; //0x14
}stAllowedEncodingVariant;
typedef enum
{
CMBS_SMS_ENC_TYPE_RESERVED,
CMBS_SMS_ENC_TYPE_GSM_7_BIT,
CMBS_SMS_ENC_TYPE_GSM_8_BIT,
CMBS_SMS_ENC_TYPE_UCS_2,
CMBS_SMS_ENC_TYPE_UTF_8,
CMBS_SMS_ENC_TYPE_MAX,
}e_SMSCharacterEncodingType;
typedef enum
{
MARK_LEAVE_UNCHANGED,
MARK_CLEAR,
MARK_SET
} eMarkRequest;
/* Entry Max Size */
typedef union
{
stContactListEntry ContactListEntry;
stCallsListEntry CallsListEntry;
stLineSettingsListEntry LineSettingsListEntry;
stSMSListEntry SMSListEntry;
}uEntryTypes;
#define LIST_ENTRY_MAX_SIZE sizeof(uEntryTypes)
/*******************************************
Globals
********************************************/
/*******************************************
List API
********************************************/
/* Initialize Lists Application */
LIST_RC List_Init(void);
/* Destory Lists Application */
LIST_RC List_Close(void);
/* Create List in database */
LIST_RC List_CreateList(IN LIST_TYPE ListType);
/* Get number of entries */
LIST_RC List_GetCount(IN LIST_TYPE ListType, OUT u32* pu32_Count);
/* Get Supported fields */
LIST_RC List_GetSupportedFields(IN LIST_TYPE ListType,
OUT u32 pu32_EditableFieldsIds[], INOUT u32* pu32_EditableSize, /* Editable Fields */
OUT u32 pu32_NonEditableFields[], INOUT u32* pu32_NonEditableSize /* Non-Editable Fields */);
/* Insert *NEW* Entry
*NOTE: For calls list, the data base automatically sets the 'call type' field, according to list type*
Input Arguments:
------------------
ListType - List to insert entry
pv_Entry - pointer to actual entry
pu32Fields - Fields used in provided entry (array of Ids)
u32_FieldsSize - size of array
Output Arguments:
------------------
pu32_EntryId - ID of inserted entry
*/
LIST_RC List_InsertEntry(IN LIST_TYPE ListType, IN void* pv_Entry, IN u32 pu32Fields[], IN u32 u32_FieldsSize, OUT u32* pu32_EntryId);
/* Delete a single entry from the database */
LIST_RC List_DeleteEntry(IN LIST_TYPE ListType, IN u32 u32_EntryId);
/* Delete all entries from the database */
LIST_RC List_DeleteAllEntries(IN LIST_TYPE ListType);
/* Update (existing) Entry */
LIST_RC List_UpdateEntry(IN LIST_TYPE ListType, IN void* pv_Entry, IN u32 pu32Fields[], IN u32 u32_FieldsSize, IN u32 u32_EntryId);
/* Read entries
Input Arguments:
------------------------
ListType - requested list
pu32_StartIndex - start index in respect to sorting fields
bForward - Direction of read
eMark - Flag for requesting resetting (or setting) of the 'Read status' field for all read entries
pu32Fields - Array of requested fields
u32_FieldsSize - size of pu32Fields
u32_SortField1 - most significant sort field
u32_SortField2 - least significant sort field (use invalid_id if not needed)
u32_EntriesSize - number of requested entries
Output Arguments:
------------------------
pv_Entries - array of read entries
pu32_EntriesSize - size of pv_Entries
pu32_StartIndex - the minimum returned entries' indices
*/
LIST_RC List_ReadEntries(IN LIST_TYPE ListType, INOUT u32* pu32_StartIndex, IN bool bForward, IN eMarkRequest eMark, IN u32 pu32Fields[], IN u32 u32_FieldsSize,
IN u32 u32_SortField1, IN u32 u32_SortField2, OUT void* pv_Entries, INOUT u32* pu32_EntriesSize);
/* Read entry by ID
Input Arguments:
------------------------
ListType - requested list
u32_EntryId - Id Of requested entry
pu32Fields - Array of requested fields
u32_FieldsSize - size of pu32Fields
Output Arguments:
------------------------
pv_Entry - pointer to read entry
*/
LIST_RC List_ReadEntryById(IN LIST_TYPE ListType, IN u32 u32_EntryId, IN u32 pu32Fields[], IN u32 u32_FieldsSize, OUT void* pv_Entry);
/* Search entries
Input Arguments:
------------------------
ListType - requested list
eMatchOption - what to return in case of no exact match (return nothing, return first greater than, return first lesser than)
bCaseSensitive - case sensitivity of the search
sSearchedVal - the value to search for
bForward - Direction of read
eMark - Flag for requesting resetting (or setting) of the 'Read status' field for all read entries
pu32Fields - Array of requested fields
u32_FieldsSize - size of pu32Fields
u32_SortField1 - most significant sort field
u32_SortField2 - least significant sort field (use invalid_id if not needed)
u32_EntriesSize - number of requested entries
Output Arguments:
------------------------
pv_Entries - array of read entries
pu32_EntriesSize - size of pv_Entries
pu32_StartIndex - index of first returned entry
*/
LIST_RC List_SearchEntries(IN LIST_TYPE ListType, IN eMatchOption eMatching, IN bool bCaseSensitive, IN const char* sSearchedVal,
IN bool bForward, IN eMarkRequest eMark, IN u32 pu32Fields[], IN u32 u32_FieldsSize,
IN u32 u32_SortField1, IN u32 u32_SortField2, OUT void* pv_Entries, INOUT u32* pu32_EntriesSize,
OUT u32* pu32_StartIndex);
/* Get Entry Index */
LIST_RC List_GetEntryIdex(IN LIST_TYPE ListType, IN u32 u32_SortField1, IN u32 u32_SortField2, IN u32 u32_EntryId, OUT u32* pu32_Index);
/*******************************************
Auxiliary
********************************************/
/* prepare strings of fields and values from the given Entry */
LIST_RC List_PrepareContactListEntryForInsert(IN stContactListEntry* pst_Entry, IN u32 pu32Fields[], IN u32 u32_FieldsSize,
OUT char sFields[], INOUT u32* pu32_FieldsSize,
OUT char sValues[], INOUT u32* pu32_ValuesSize);
LIST_RC List_PrepareCallsListEntryForInsert(IN LIST_TYPE ListType, IN stCallsListEntry* pst_Entry, IN u32 pu32Fields[], IN u32 u32_FieldsSize,
OUT char sFields[], INOUT u32* pu32_FieldsSize,
OUT char sValues[], INOUT u32* pu32_ValuesSize);
LIST_RC List_PrepareLineSettingsListEntryForInsert(IN stLineSettingsListEntry* pst_Entry, IN u32 pu32Fields[], IN u32 u32_FieldsSize,
OUT char sFields[], INOUT u32* pu32_FieldsSize,
OUT char sValues[], INOUT u32* pu32_ValuesSize);
LIST_RC List_PrepareLineAndDiagnosticistEntryForInsert(IN stLineAndDiagnosticListEntry* pst_Entry, IN u32 pu32Fields[], IN u32 u32_FieldsSize,
OUT char sFields[], INOUT u32* pu32_FieldsSize,
OUT char sValues[], INOUT u32* pu32_ValuesSize);
LIST_RC List_PrepareSMSSettingsListEntryForInsert(IN stSMSSettingsListEntry* pst_Entry, IN u32 pu32Fields[], IN u32 u32_FieldsSize,
OUT char sFields[], INOUT u32* pu32_FieldsSize,
OUT char sValues[], INOUT u32* pu32_ValuesSize);
LIST_RC List_PrepareSMSListEntryForInsert(IN LIST_TYPE ListType, IN stSMSListEntry* pst_Entry, IN u32 pu32Fields[], IN u32 u32_FieldsSize,
OUT char sFields[], INOUT u32* pu32_FieldsSize,
OUT char sValues[], INOUT u32* pu32_ValuesSize);
LIST_RC List_PrepareDTAMSettingsListEntryForInsert(IN stDTAMSettingsListEntry* pst_Entry, IN u32 pu32Fields[], IN u32 u32_FieldsSize,
OUT char sFields[], INOUT u32* pu32_FieldsSize,
OUT char sValues[], INOUT u32* pu32_ValuesSize);
LIST_RC List_PrepareDTAMWelcomeMsgListEntryForInsert(IN stDTAMWelcomeMessageListEntry* pst_Entry, IN u32 pu32Fields[], IN u32 u32_FieldsSize,
OUT char sFields[], INOUT u32* pu32_FieldsSize,
OUT char sValues[], INOUT u32* pu32_ValuesSize);
LIST_RC List_PrepareContactListEntryForUpdate(IN stContactListEntry* pst_Entry, IN u32 pu32Fields[], IN u32 u32_FieldsSize,
OUT char sFields[], INOUT u32* pu32_FieldsSize);
LIST_RC List_PrepareCallsListEntryForUpdate(IN stCallsListEntry* pst_Entry, IN u32 pu32Fields[], IN u32 u32_FieldsSize,
OUT char sFields[], INOUT u32* pu32_FieldsSize);
LIST_RC List_PrepareLineSettingsListEntryForUpdate(IN stLineSettingsListEntry* pst_Entry, IN u32 pu32Fields[], IN u32 u32_FieldsSize,
OUT char sFields[], INOUT u32* pu32_FieldsSize);
LIST_RC List_PrepareLineAndDiagnosticEntryForUpdate(IN stLineAndDiagnosticListEntry* pst_Entry, IN u32 pu32Fields[], IN u32 u32_FieldsSize,
OUT char sFields[], INOUT u32* pu32_FieldsSize);
LIST_RC List_PrepareSMSSettingsListEntryForUpdate(IN stSMSSettingsListEntry* pst_Entry, IN u32 pu32Fields[], IN u32 u32_FieldsSize,
OUT char sFields[], INOUT u32* pu32_FieldsSize);
LIST_RC List_PrepareSMSListEntryForUpdate(IN stSMSListEntry* pst_Entry, IN u32 pu32Fields[], IN u32 u32_FieldsSize,
OUT char sFields[], INOUT u32* pu32_FieldsSize);
LIST_RC List_PrepareDTAMSettingsListEntryForUpdate(IN stDTAMSettingsListEntry* pst_Entry, IN u32 pu32Fields[], IN u32 u32_FieldsSize,
OUT char sFields[], INOUT u32* pu32_FieldsSize);
LIST_RC List_PrepareDTAMWelcomeMsgListEntryForUpdate(IN stDTAMWelcomeMessageListEntry* pst_Entry, IN u32 pu32Fields[], IN u32 u32_FieldsSize,
OUT char sFields[], INOUT u32* pu32_FieldsSize);
/* prepare string with fields names from the given field Ids */
LIST_RC List_PrepareFieldsNamesForRead(IN LIST_TYPE ListType, IN u32 pu32Fields[], IN u32 u32_FieldsSize,
OUT char sFields[], INOUT u32* pu32_FieldsSize,
OUT bool* pb_JoinContactList, OUT bool* pb_JoinLineSettingsList);
/* Fill Entry */
LIST_RC List_FillEntry(IN LIST_TYPE ListType, IN u32 pu32Fields[], IN u32 u32_FieldsSize, OUT void* pv_Entries, IN u32 u32_EntriesOffset,
IN void* pv_SelectHandle, IN PST_COLUMN_MAP pst_Map);
LIST_RC List_FillContactListEntry(IN u32 pu32Fields[], IN u32 u32_FieldsSize, OUT void* pv_Entries, IN u32 u32_EntriesOffset,
IN void* pv_SelectHandle, IN PST_COLUMN_MAP pst_Map);
LIST_RC List_FillCallsListEntry(IN u32 pu32Fields[], IN u32 u32_FieldsSize, OUT void* pv_Entries, IN u32 u32_EntriesOffset,
IN void* pv_SelectHandle, IN PST_COLUMN_MAP pst_Map);
LIST_RC List_FillLineSettingsEntry(IN u32 pu32Fields[], IN u32 u32_FieldsSize, OUT void* pv_Entries, IN u32 u32_EntriesOffset,
IN void* pv_SelectHandle, IN PST_COLUMN_MAP pst_Map);
LIST_RC List_FillLineDiagnosticEntry(IN u32 pu32Fields[], IN u32 u32_FieldsSize, OUT void* pv_Entries, IN u32 u32_EntriesOffset,
IN void* pv_SelectHandle, IN PST_COLUMN_MAP pst_Map);
LIST_RC List_FillSMSSettingsListEntry(IN u32 pu32Fields[], IN u32 u32_FieldsSize, OUT void* pv_Entries, IN u32 u32_EntriesOffset,
IN void* pv_SelectHandle, IN PST_COLUMN_MAP pst_Map);
LIST_RC List_FillSMSListEntry(IN u32 pu32Fields[], IN u32 u32_FieldsSize, OUT void* pv_Entries, IN u32 u32_EntriesOffset,
IN void* pv_SelectHandle, IN PST_COLUMN_MAP pst_Map);
LIST_RC List_FillDTAMSettingsListEntry(IN u32 pu32Fields[], IN u32 u32_FieldsSize, OUT void* pv_Entries, IN u32 u32_EntriesOffset,
IN void* pv_SelectHandle, IN PST_COLUMN_MAP pst_Map);
LIST_RC List_FillDTAMWelcomeMsgEntry(IN u32 pu32Fields[], IN u32 u32_FieldsSize, OUT void* pv_Entries, IN u32 u32_EntriesOffset,
IN void* pv_SelectHandle, IN PST_COLUMN_MAP pst_Map);
/* Attached Handsets */
LIST_RC List_GetAttachedHs(IN u32 u32_LineId, OUT u32* pu32_AttachedHsMask);
LIST_RC List_SetAttachedHs(IN u32 u32_LineId, IN u32 u32_AttachedHsMask);
/* Missed Calls Num Of Read / Unread Entries */
LIST_RC List_GetMissedCallsNumOfEntries(IN u32 u32_LineId, OUT u32* pu32_NumOfUnread, OUT u32* pu32_NumOfRead);
/* Add HS to first line's Attached HS mask */
LIST_RC List_AddHsToFirstLine(IN u8 u8_HsNum);
/* Remove HS from all lines' Attahced HS mask */
LIST_RC List_RemoveHsFromAllLines(IN u8 u8_HsNum);
/* Returns the first line that the input HS is attached to,
or the first line in the system if the HS is not attached to any line */
LIST_RC List_GetDefaultLine(IN u8 u8_HsNum, OUT u32* pu32_LineId);
/* returns list of lines the input HS is attached to */
LIST_RC List_GetLinesOfHS( IN u8 u8_HsNum, OUT u32 pu32_LineId[], INOUT u32* pu32_LineIdLen );
/* returns Call Forward Enabled / Diabled for the specified line */
LIST_RC List_GetCallForwardMode( IN u32 u32_LineID, OUT u8* pb_CFUncondEn, OUT u8* pb_CFNoAnsEn,OUT u8* pb_CFBusyEn );
/* adds default Line entry with 5 attached HS */
LIST_RC List_AddDefaultLine();
/* Checks Line Use status, if changed - updates data base and sends notification */
bool LineAndDiagnosticListUpdateLineUse(u8 LineId, E_CMBS_LINE_DIAG_STATUS eLineStatus);
/* Updates HS Use status in data base */
LIST_RC LineAndDiagnosticListUpdateHSUse(u8 LineId, u32 u32_HSNum, bool b_InUse);
/* Updates OK status in data base */
LIST_RC LineAndDiagnosticListUpdateOKStatus(u8 LineId, E_CMBS_LINE_DIAG_OK_STATUS e_DiagErrorStatus);
/* Updates Call Forward status in data base */
LIST_RC LineAndDiagnosticListUpdateCallFWD(u8 LineId, FIELD_ID FieldId, bool b_Status);
/* Updates Diagnostic Error status in data base */
LIST_RC LineAndDiagnosticListUpdateDiagnosticErrorStatus(u8 LineId, bool b_Status, E_CMBS_LINE_DIAG_ERROR_TYPE e_ErrorType, u8 u8_ErrorNumber);
/* Add "system" entry to Line and diagnostic status list */
LIST_RC List_AddLineAndDiagnosticSystemEntry();
/* Clears Line and HS use status fields in line and diagnostic status list entry */
LIST_RC List_ClearLineAndDiagnosticSystemEntry();
/* Return current line use status from line and diagnostic status list */
E_CMBS_LINE_DIAG_STATUS LineAndDiagnosticListGetLineUseStatus(u8 LineId);
/* Return Number of read and unread entries*/
LIST_RC List_GetSMSNumOfEntries(IN u32 u32_SMSId, OUT u32 * pu32_NumOfUnread, OUT u32 * pu32_NumOfRead);
/* Return current HS use status from line and diagnostic status list */
u32 LineAndDiagnosticListGetHSUseStatus(u8 LineId);
LIST_RC List_GetOutgoingCallsNumOfEntries(IN u32 u32_LineId, OUT u32* pu32_NumOfEntries);
/* Set Originating PP for List Change Details */
LIST_RC List_SetListChangeOriginatingHandset( IN LIST_TYPE ListType, IN u8 u8_HsNum);
/* Add List Change Details */
LIST_RC List_AddListChangeDetails( IN LIST_TYPE ListType, IN ST_APP_FACILITY_LCN_SUB_DETAILS *pst_LcnSubDetails);
/* Reset List Change Details for all lists */
LIST_RC List_ResetAllListChangeDetails( void );
/* Reset List Change Details for specific list */
LIST_RC List_ResetListChangeDetails( IN LIST_TYPE ListType);
/* Get List Change Details for specific list */
LIST_RC List_GetListChangeDetails( IN LIST_TYPE ListType, OUT ST_APP_FACILITY_LCN_DETAILS **pst_LcnDetails);
#endif /* __LISTS_APP_H__ */
/* End Of File *****************************************************************************************************************************/

View File

@@ -0,0 +1,389 @@
/*************************************************************************************************************
*** SQLiteWrapper
*** Clear C interface on top of SQLite 3
**
**************************************************************************************************************/
/*******************************************
Includes
********************************************/
#include <stdio.h>
#include "SQLiteWrapper.h"
#include "cmbs_platf.h"
#include "cfr_debug.h"
#ifdef __linux
#include <pthread.h>
#endif
/*******************************************
Defines
********************************************/
#define MUTEX g_Database.cs_mutex
#define DATABASE(x) g_Database.pDB_DataBase[x]
/*******************************************
Globals
********************************************/
ST_SQL_DB g_Database;
/*******************************************
Interface API
********************************************/
SQL_RC SQL_InitDatabase(void)
{
u32 u32_index = 0;
/* create mutex */
CFR_CMBS_INIT_CRITICALSECTION(MUTEX);
/* init database handles */
for (u32_index = 0; u32_index < SQL_MAX_SIMULTANEOUS_DB_ACCESS; ++u32_index)
{
DATABASE(u32_index) = NULL;
}
return SQL_RC_OK;
}
SQL_RC SQL_CloseDatabase(void)
{
u32 u32_index = 0;
/* close database handles */
for (u32_index = 0; u32_index < SQL_MAX_SIMULTANEOUS_DB_ACCESS; ++u32_index)
{
if(DATABASE(u32_index) != NULL){
sqlite3_close(DATABASE(u32_index));
DATABASE(u32_index) = NULL;
}
}
return SQL_RC_OK;
}
SQL_RC SQL_GetDatabaseHandle(void** ppv_DBHandle)
{
u32 u32_rc = 0;
u32 u32_index = 0;
/* Enter critical section */
CFR_CMBS_ENTER_CRITICALSECTION(MUTEX);
/* find free handle */
for (u32_index = 0; u32_index < SQL_MAX_SIMULTANEOUS_DB_ACCESS; ++u32_index)
{
if (DATABASE(u32_index) == NULL)
{
/* found! */
/* open Database */
u32_rc = sqlite3_open(LIST_ACCESS_DB_FILE, &DATABASE(u32_index));
if (u32_rc)
{
printf("Can't open database: %s\n", LIST_ACCESS_DB_FILE);
sqlite3_close(DATABASE(u32_index));
/* Leave critical section */
CFR_CMBS_LEAVE_CRITICALSECTION(MUTEX);
return SQL_RC_FAIL;
}
else
{
/* Leave critical section */
*ppv_DBHandle = DATABASE(u32_index);
CFR_CMBS_LEAVE_CRITICALSECTION(MUTEX);
return SQL_RC_OK;
}
}
}
printf("No more free DB handles\n");
/* Leave critical section */
CFR_CMBS_LEAVE_CRITICALSECTION(MUTEX);
return SQL_RC_FAIL;
}
SQL_RC SQL_ReturnDatabaseHandle(void* pv_DBHandle)
{
u32 u32_rc = 0;
u32 u32_index = 0;
/* Enter critical section */
CFR_CMBS_ENTER_CRITICALSECTION(MUTEX);
/* find the handle */
for (u32_index = 0; u32_index < SQL_MAX_SIMULTANEOUS_DB_ACCESS; ++u32_index)
{
if (DATABASE(u32_index) == pv_DBHandle)
{
/* found! */
/* close Database */
u32_rc = sqlite3_close(pv_DBHandle);
if (u32_rc)
{
printf("Can't close database!\n");
/* Leave critical section */
CFR_CMBS_LEAVE_CRITICALSECTION(MUTEX);
return SQL_RC_FAIL;
}
else
{
/* Leave critical section */
DATABASE(u32_index) = NULL;
CFR_CMBS_LEAVE_CRITICALSECTION(MUTEX);
return SQL_RC_OK;
}
}
}
printf("Unknown DB Handle %p\n", pv_DBHandle);
/* Leave critical section */
CFR_CMBS_LEAVE_CRITICALSECTION(MUTEX);
return SQL_RC_FAIL;
}
SQL_RC SQL_Execute(void* pv_DBHandle, const char* s_Query)
{
u32 u32_rc = 0;
sqlite3_stmt* pResult_res = NULL;
/* prepare query */
u32_rc = sqlite3_prepare(pv_DBHandle, s_Query, (s32)strlen(s_Query) + 1, &pResult_res, NULL);
if (u32_rc != SQLITE_OK)
{
printf("execute: prepare query failed\n");
return SQL_RC_FAIL;
}
if (!pResult_res)
{
printf("execute: query failed\n");
return SQL_RC_FAIL;
}
/* execute */
u32_rc = sqlite3_step(pResult_res);
/* deallocate statement */
sqlite3_finalize(pResult_res);
pResult_res = NULL;
/* check result */
switch (u32_rc)
{
case SQLITE_BUSY:
printf("execute: database busy\n");
return SQL_RC_FAIL;
case SQLITE_DONE:
case SQLITE_ROW:
return SQL_RC_OK;
case SQLITE_ERROR:
printf("Error %s\n", sqlite3_errmsg(pv_DBHandle));
return SQL_RC_FAIL;
case SQLITE_MISUSE:
printf("execute: database misuse\n");
return SQL_RC_FAIL;
default:
printf("execute: unknown result code\n");
}
return SQL_RC_FAIL;
}
SQL_RC SQL_Select(void* pv_DBHandle, const char* s_Query, bool b_PrepareMap, PST_COLUMN_MAP pst_pMap, void** ppv_SelectHandle)
{
u32 u32_rc = 0;
sqlite3_stmt* pResult_res = NULL;
/* prepare query */
u32_rc = sqlite3_prepare(pv_DBHandle, s_Query, (s32)strlen(s_Query) + 1, &pResult_res, NULL);
if (u32_rc != SQLITE_OK)
{
printf("get_result: prepare query failed\n");
return SQL_RC_FAIL;
}
if (pResult_res == NULL)
{
printf("get_result: query failed\n");
return SQL_RC_FAIL;
}
*ppv_SelectHandle = pResult_res;
/* prepare column map (if requested) */
if (b_PrepareMap)
{
u32 u32_index = 0;
const char* ps_ColumnName = NULL;
do
{
ps_ColumnName = sqlite3_column_name(pResult_res, u32_index);
if (ps_ColumnName == NULL)
break;
strcpy(pst_pMap->column_map[u32_index++], ps_ColumnName);
} while (TRUE);
pst_pMap->u32_NumOfColumns = u32_index;
}
return SQL_RC_OK;
}
SQL_RC SQL_FetchRow(void* pv_SelectHandle, bool* pb_NextRowAvailable)
{
u32 u32_rc = 0;
*pb_NextRowAvailable = FALSE;
/* execute the query */
u32_rc = sqlite3_step(pv_SelectHandle);
switch (u32_rc)
{
case SQLITE_ROW:
*pb_NextRowAvailable = TRUE;
return SQL_RC_OK;
case SQLITE_BUSY:
printf("execute: database busy\n");
return SQL_RC_OK;
case SQLITE_DONE:
return SQL_RC_OK;
case SQLITE_ERROR:
printf("General Error\n");
return SQL_RC_FAIL;
case SQLITE_MISUSE:
printf("execute: database misuse\n");
return SQL_RC_FAIL;
default:
printf("execute: unknown result code\n");
return SQL_RC_FAIL;
}
}
SQL_RC SQL_ReleaseSelectHandle(void* pv_SelectHandle)
{
u32 u32_rc = sqlite3_finalize(pv_SelectHandle);
if (u32_rc)
{
printf("Failed releasing select handle\n");
return SQL_RC_FAIL;
}
else
{
return SQL_RC_OK;
}
}
s32 GetIdxByName(const char* ps_Name, PST_COLUMN_MAP pst_pMap)
{
u32 u32_index;
for (u32_index = 0; u32_index < pst_pMap->u32_NumOfColumns; ++u32_index)
{
if (strcmp(ps_Name, pst_pMap->column_map[u32_index]) == 0)
{
/* found */
return u32_index;
}
}
return -1;
}
SQL_RC SQL_GetStrByIdx(void* pv_SelectHandle, u32 u32_index, const unsigned char** pps_value)
{
*pps_value = sqlite3_column_text(pv_SelectHandle, u32_index);
if (*pps_value == NULL)
{
*pps_value = (const unsigned char*)"";
}
return SQL_RC_OK;
}
SQL_RC SQL_GetStrByColumnName(void* pv_SelectHandle, const char* ps_ColumnName, PST_COLUMN_MAP pst_pMap, const unsigned char** pps_value)
{
s32 s32_index = GetIdxByName(ps_ColumnName, pst_pMap);
if (s32_index >= 0)
{
return SQL_GetStrByIdx(pv_SelectHandle, s32_index, pps_value);
}
printf("Column name lookup failure: %s", ps_ColumnName);
return SQL_RC_FAIL;
}
SQL_RC SQL_GetUValByIdx(void* pv_SelectHandle, u32 u32_index, u32* pu32_value)
{
*pu32_value = sqlite3_column_int(pv_SelectHandle, u32_index);
return SQL_RC_OK;
}
SQL_RC SQL_GetUVal64ByIdx(void* pv_SelectHandle, u32 u32_index, u64* pu64_value)
{
*pu64_value = sqlite3_column_int64(pv_SelectHandle, u32_index);
return SQL_RC_OK;
}
SQL_RC SQL_GetUValByColumnName(void* pv_SelectHandle, const char* ps_ColumnName, PST_COLUMN_MAP pst_pMap, u32* pu32_value)
{
s32 s32_index = GetIdxByName(ps_ColumnName, pst_pMap);
if (s32_index >= 0)
{
return SQL_GetUValByIdx(pv_SelectHandle, s32_index, pu32_value);
}
printf("Column name lookup failure: %s", ps_ColumnName);
return SQL_RC_FAIL;
}
SQL_RC SQL_GetUVal64ByColumnName(IN void* pv_SelectHandle, IN const char* ps_ColumnName, IN PST_COLUMN_MAP pst_pMap, OUT u64* pu64_value)
{
s32 s32_index = GetIdxByName(ps_ColumnName, pst_pMap);
if (s32_index >= 0)
{
return SQL_GetUVal64ByIdx(pv_SelectHandle, s32_index, pu64_value);
}
CFR_DBG_ERROR("Column name lookup failure: %s", ps_ColumnName);
return SQL_RC_FAIL;
}
SQL_RC SQL_GetIdOfLastInsert(void* pv_DBHandle, u32* pu32_Id)
{
*pu32_Id = (u32)sqlite3_last_insert_rowid(pv_DBHandle);
return SQL_RC_OK;
}
/* End Of File *****************************************************************************************************************************/

View File

@@ -0,0 +1,143 @@
/*************************************************************************************************************
*** SQLiteWrapper
*** Clear C interface on top of SQLite 3
**
**************************************************************************************************************/
#ifndef __SQLITE_WRAPPER_H__
#define __SQLITE_WRAPPER_H__
/*******************************************
Includes
********************************************/
#ifndef WIN32
#include <fcntl.h>
#else
#include "windows.h"
#endif
#include "cmbs_api.h"
#include "cfr_mssg.h"
#include "sqlite3.h"
/*******************************************
Defines
********************************************/
#ifdef CMBS_HOST_RO_FILE_SYSTEM // read only file system
#define LIST_ACCESS_DB_FILE "/tmp/LA_DB"
#else
#define LIST_ACCESS_DB_FILE "LA_DB"
#endif
#define SQL_MAX_COLUMNS 30
#define SQL_MAX_COLUMN_NAME_LEN 40
#define SQL_MAX_SIMULTANEOUS_DB_ACCESS 5
#define SQL_QUERY_MAX_LEN 1024
/*******************************************
Types
********************************************/
typedef struct
{
CFR_CMBS_CRITICALSECTION cs_mutex;
sqlite3* pDB_DataBase[SQL_MAX_SIMULTANEOUS_DB_ACCESS];
} ST_SQL_DB, * PST_SQL_DB;
typedef struct
{
char column_map[SQL_MAX_COLUMNS][SQL_MAX_COLUMN_NAME_LEN + 1];
u32 u32_NumOfColumns;
} ST_COLUMN_MAP, * PST_COLUMN_MAP;
typedef enum
{
SQL_RC_OK = 0,
SQL_RC_FAIL = 1
} SQL_RC;
/*******************************************
Interface API
********************************************/
/* Init DataBase */
SQL_RC SQL_InitDatabase(void);
/* Close DataBase */
SQL_RC SQL_CloseDatabase(void);
/* Get Database Handle */
SQL_RC SQL_GetDatabaseHandle(OUT void** ppv_DBHandle);
/* Return Database Handle */
SQL_RC SQL_ReturnDatabaseHandle(IN void* pv_DBHandle);
/* Send SQL Query */
SQL_RC SQL_Execute(IN void* pv_DBHandle, IN const char* s_Query);
/* SQL Select from a table
**
** After a call to Select function, the user should call to FetchRow one or more times (depends on how many rows exist
** and how many the user wants to read), and finally ReleaseSelectHandle
**
** Input Args:
** -----------------
** pv_DBHandle - pointer to DB
** s_Query - string SQL query
** b_PrepareMap - should a map be prepared
** if b_PrepareMap is non-zero,
** the function will return a mapping between column index and column name
** the map will be returned on pst_pMap - caller should allocate it!
**
** Output Args
** -------------------
** pst_pMap - pointer to map object
** ppv_SelectHandle - pointer to SelectHandle (to be used on subsequent GetRow calls - user is responsible to call to ReleaseSelectHandle !!!
** */
SQL_RC SQL_Select(IN void* pv_DBHandle, IN const char* s_Query, IN bool b_PrepareMap, OUT PST_COLUMN_MAP pst_pMap, OUT void** ppv_SelectHandle);
/* Order the Database to Get The next row, corresponds to the last select query performed
Input Arguments
--------------------
pv_SelectHandle - Handle to the appropriate select query
Output Argument
--------------------
b_NextRowAvailable - if non-zero, it means that there is another row, and the user may extract its data from the data base (using getstr, getuvalue,
etc. - depends on the data type)
*/
SQL_RC SQL_FetchRow(IN void* pv_SelectHandle, OUT bool* pb_NextRowAvailable);
SQL_RC SQL_ReleaseSelectHandle(IN void* pv_SelectHandle);
/* Get the (string) value in the current row, at the given column index */
SQL_RC SQL_GetStrByIdx(IN void* pv_SelectHandle, IN u32 u32_index, OUT const unsigned char** pps_value);
/* Get the (string) value in the current row, at the given column name */
SQL_RC SQL_GetStrByColumnName(IN void* pv_SelectHandle, IN const char* ps_ColumnName, IN PST_COLUMN_MAP pst_pMap, OUT const unsigned char** pps_value);
/* Get the (unsigned integer) value in the current row, at the given column index */
SQL_RC SQL_GetUValByIdx( IN void* pv_SelectHandle, IN u32 u32_index, OUT u32* pu32_value);
SQL_RC SQL_GetUVal64ByIdx(IN void* pv_SelectHandle, IN u32 u32_index, OUT u64* pu64_value);
/* Get the (unsigned integer) value in the current row, at the given column name */
SQL_RC SQL_GetUValByColumnName( IN void* pv_SelectHandle, IN const char* ps_ColumnName, IN PST_COLUMN_MAP pst_pMap, OUT u32* pu32_value);
SQL_RC SQL_GetUVal64ByColumnName(IN void* pv_SelectHandle, IN const char* ps_ColumnName, IN PST_COLUMN_MAP pst_pMap, OUT u64* pu64_value);
/* Get the Id of last insert */
SQL_RC SQL_GetIdOfLastInsert(IN void* pv_DBHandle, OUT u32* pu32_Id);
/*******************************************
Auxiliary
********************************************/
/* searches for the given name in the given map, and return index. return -1 when not found */
s32 GetIdxByName(IN const char* ps_Name, IN PST_COLUMN_MAP pst_pMap);
#endif /* __SQLITE_WRAPPER_H__ */
/* End Of File *****************************************************************************************************************************/

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

295
dectmngr/src/app/Makefile Normal file
View File

@@ -0,0 +1,295 @@
################################################################################
#
# Copyright 2010 DSP Group
#
# Author : Ralf Stein, Dirk Kelbch
# Date : 09-Feb-2009
#
# History
# ----------------------------------------------------------------------------
# tcmc_asa 19-Apr-2011 13 add TESTDIR and testout
#
#################################################################################
.KEEP_STATE:
.SUFFIXES:
.SUFFIXES: .c .cpp .h .hpp .asm .s .inc .o .elf .d .dep .def .lex .y .ypp
libraries :=
symfiles :=
objects :=
linkpath :=
APPNAME := dectmngr
ifeq ($(OS),Windows_NT)
HOST_OS = WIN32
ifndef HOST_DLL_SUPPORT
HOST_DLL_SUPPORT :=1
endif
else
HOST_OS = UNIX
endif
ifdef SHELL
ifeq ($(notdir $(basename $(SHELL))),cmd)
### SHELL=cmd.exe
RM := del /Q
SL := \$(EMPTY)
else
### SHELL=sh
RM := rm -f
SL := /
endif
else
RM := del /Q
SL := \$(EMPTY)
endif
# To compile without CURL comment the next line
# SUOTA_CURL = true
################################################################################
#
# Directory
#
# define output,intermediate, object, project and base directory
#
ifeq ($(BASE),)
BASE :=.
else
CMBSDIR := ..
endif
PROJDIR := ..
TESTDIR :=.
OUTDIR := $(BASE)
OBJDIR := $(BASE)$(SL)obj
ifeq ($(LIBDIR),)
LIBDIR := $(PROJDIR)$(SL)lib
endif
# To block HAN_SERVER comment next line:
HAN_SERVER = true
# will compile the han demo + to FB
ifeq ($(DVF99),1)
HAN_SERVER_DEMO_CROSS_COMPILE = true
CMBS_COMA = true
ifndef LIBCOMA
LIBCOMA:=../tools/coma/libcoma-api
endif
ifndef LIBMEM
LIBMEM:=../comatools/tools/libcmem
endif
endif
CMBS_HOST := true
################################################################################
#
# C-Option definition
#
#
# -DHAN_SERVER_DEMO_CISCO
ifdef HAN_SERVER
coptions := -DHAN_SERVER
else
coptions :=
endif
CMBS_BUF_SIZE := 2560
# CMBS_BUF_SIZE must be a multiply of 20 (8 * 2.5) because CMBS_PARAM_MAX_LENGTH is CMBS_BUF_SIZE/2.5 and it must be multiply of 8
coptions += -DCMBS_API -DDNA_TAG -DCHECKSUM_SUPPORT -D_CONSOLE -DCMBS_BUF_SIZE=$(CMBS_BUF_SIZE) -DCATIQ_2_1 -DSUOTA_SDU_CHOPPING -DSUOTA_APP
# New host logging functions(with timestamp and module name) to all cmbs_tcx module to log a file.
coptions += -DTCXLOG_FILE
# this flag wil cause appcmbs.c to use appsuotafileentity instead of appsuotaentity
ifeq ($(SUOTA_USE_LOCAL_FILE),1)
coptions += -DSUOTA_USE_LOCAL_FILE_ENTITY
endif
# this flag wil cause hanserver.c to use %x in the payload instead of %d but will not effect the FUN_CONVERT
ifeq ($(HAN_PROTOCOL_PAYLOAD_AS_HEX),1)
coptions += -DHAN_PROTOCOL_PAYLOAD_AS_HEX
endif
# AVS AUDIO APP
ifeq ($(AVS_AUDIO_APP),1)
coptions += -DAVS_AUDIO_APP
ifeq ($(AVS_CALL_RELEASE),1)
coptions += -DAVS_CALL_RELEASE
ifdef AVS_CALL_RELEASE_TIMEOUT
coptions += -DAVS_CALL_RELEASE_TIMEOUT=$(AVS_CALL_RELEASE_TIMEOUT)
endif
endif
endif
coptions += -DPNCAP
################################################################################
#
# include
#
#
includes := -I. -I$(PROJDIR)$(SL)include -I$(PROJDIR)$(SL)cmbs -I$(PROJDIR)$(SL)frame$(SL)osl$(SL)inc
includes += -I$(BASE)$(SL)han$(SL)HAN_Client$(SL)src -I$(PROJDIR)$(SL)frame$(SL)osl$(SL)linux
includes += -I$(BASE)$(SL)han$(SL)HAN_Server
includes += -I$(PROJDIR)$(SL)libdect
################################################################################
objects := $(OBJDIR)/tcx_config.o
objects += $(OBJDIR)/tcx_keyb.o
objects += $(OBJDIR)/tcx_log.o
objects += $(OBJDIR)/tcx_hostlog.o
objects += $(OBJDIR)/tcx_eep.o
objects += $(OBJDIR)/tcx_util.o
objects += $(OBJDIR)/keyb_srv.o
objects += $(OBJDIR)/keyb_call.o
objects += $(OBJDIR)/keyb_swup.o
objects += $(OBJDIR)/keyb_facility.o
objects += $(OBJDIR)/keyb_data.o
objects += $(OBJDIR)/keyb_suota.o
objects += $(OBJDIR)/keyb_han.o
objects += $(OBJDIR)/keyb_uledata.o
objects += $(OBJDIR)/keyb_rtp.o
objects += $(OBJDIR)/cmbs_voipline.o
objects += $(OBJDIR)/cmbs_event.o
objects += $(OBJDIR)/cmbs_fifo.o
objects += $(OBJDIR)/keyb_crashdump.o
objects += $(OBJDIR)/inifile.o
objects += $(OBJDIR)/appAvsService.o
objects += $(OBJDIR)/appVoipService.o
objects += $(OBJDIR)/keyb_callrouter.o
objects += $(OBJDIR)/ubus.o
objects += $(OBJDIR)/dect_common.o
objects += $(OBJDIR)/libdect_api.o
ifdef AVS_AUDIO_APP
objects += $(OBJDIR)/appaudio.o
endif
ifeq ($(DVF99),1)
ifdef CMBS_PLUGIN
objects += $(OBJDIR)/cmbs_plugin.o
endif
endif
ifeq ($(HOST_OS),WIN32)
CMBS_LIBNAME := cmbs_host_win32.lib
CMBS_LIB := $(LIBDIR)$(SL)$(CMBS_LIBNAME)
ifeq ($(HOST_DLL_SUPPORT),1)
CMBS_LIB += $(LIBDIR)$(SL)cfr_core.lib
endif
else
CMBS_LIBNAME := cmbs_host_lnx
CMBS_LIB := $(LIBDIR)/lib$(CMBS_LIBNAME).a
linkpath += -L$(LIBDIR)
endif
################################################################################
# tcx core
ifeq ($(TC),XML)
include $(CORE)$(SL)tcx$(SL)tcx.mak
endif
################################################################################
# host cmbs application
include $(TESTDIR)$(SL)appcmbs$(SL)happcmbs.mak
################################################################################
# List Access
include $(TESTDIR)$(SL)ListAccess$(SL)ListAccess.mak
################################################################################
# framework
ifeq ($(HOST_OS),WIN32)
include $(PROJDIR)$(SL)frame$(SL)win32$(SL)frame.mak
else
include $(PROJDIR)/frame/linux/frame.mak
endif
################################################################################
# CMBS
include $(PROJDIR)$(SL)cmbs$(SL)cmbs.mak
################################################################################
################################################################################
# SUOTA
include $(TESTDIR)$(SL)suota$(SL)suota.mak
################################################################################
################################################################################
# HAN Server
ifdef HAN_SERVER
include $(TESTDIR)$(SL)han$(SL)HAN_Server$(SL)server.mak
endif
################################################################################
# OSL
include $(PROJDIR)$(SL)frame$(SL)osl$(SL)linux$(SL)OSL.mak
################################################################################
################################################################################
# PNCAP
include $(TESTDIR)$(SL)ext_src$(SL)pncap$(SL)src$(SL)pncap.mak
################################################################################
# rules
ifeq ($(HOST_OS),WIN32)
include win32.mak
else
include linux.mak
endif
ifdef CMBS_COMA
COMA_LIB_DIR:=$(LIBCOMA)/linux
coptions+= -DCMBS_COMA -DUSE_COMA_SOCK
LFLAGS+= -lrt -lcoma -pthread -L $(COMA_LIB_DIR) -L /usr/local/lib
ifeq ($(SUOTA_CURL),true)
LFLAGS+= -lgcrypt -lgnutls -lgpg-error -ltasn1
endif
endif
ifeq ($(NBS),1)
coptions += -DNBS=1
endif
ifdef CMBS_PLUGIN
coptions+= -DCMBS_PLUGIN
LFLAGS+= -rdynamic -ldl
endif
all: dirs $(OUTDIR)/$(APPNAME) $(OUTDIR)/libdect.so
dirs: $(OBJDIR) $(LIBDIR)
$(OBJDIR):
mkdir -p $(OBJDIR)
$(LIBDIR):
mkdir -p $(LIBDIR)
$(CMBS_LIB): $(cfr_objects) $(cmbs_objects)
$(ARCHIEVE) $(cfr_objects) $(cmbs_objects)
$(OBJDIR)/main.o: main.c
$(CC) $(CFLAGS) $(includes) $(coptions) -c -o $@ $<
$(OBJDIR)/tcx_cmbs_lib.o: main.c
$(CC) $(CFLAGS) $(includes) $(coptions) -DGEN_LIBDECT -c -o $@ $<
$(OBJDIR)/libdect_api.o: ../libdect/libdect_api.c
$(CC) $(CFLAGS) $(includes) $(coptions) -c -o $@ $<
clean:
$(RM) -fr $(OBJDIR) $(LIBDIR)
mframe:
$(LINK) -shared -nostartfiles -o libRTPFramePlugin.so mframe_plugin.c cfifo.c rtp_jpeg.c frame_jpeg.c -lrt -lmem -lcoma -lpthread -L$(LIBMEM) -I$(LIBMEM) -I$(LIBCOMA)/inc -I$(LIBCOMA) -DUSE_COMA_SOCK -DCMBS_FRAME_DATA_RT -DCMBS_BUF_SIZE=$(CMBS_BUF_SIZE) -L $(COMA_LIB_DIR) -I$(PROJDIR)$(SL)include -I$(PROJDIR)$(SL)cmbs
$(OUTDIR)/$(APPNAME): $(CMBS_LIB) $(OBJDIR)/main.o $(objects)
$(CC) $(CFLAGS) $(LFLAGS) -o $@ $^ $(LIBS) -L$(PROJDIR)/lib
$(OUTDIR)/libdect.so: $(CMBS_LIB) $(OBJDIR)/tcx_cmbs_lib.o $(objects)
$(CC) $(CFLAGS) $(LFLAGS) -shared -o $@ $^ $(LIBS) -L$(PROJDIR)/lib

View File

@@ -0,0 +1,408 @@
/*************************************************************************************************************
*** UDP Storage source
**
**************************************************************************************************************/
/*******************************************
Includes
********************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef WIN32
#include <windows.h>
#else
#include <pthread.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#endif
#include "UDPStorageServer.h"
#include "tcx_hostlog.h"
#define APP_STORAGE_INFO_PRINT(format, ...) tcx_WriteLog(UDP_STORAGE_MODULE, LOG_LEVEL_INFO, format, ##__VA_ARGS__ )
#define APP_STORAGE_TRACE_PRINT(format, ...) tcx_WriteLog(UDP_STORAGE_MODULE, LOG_LEVEL_TRACE, format, ##__VA_ARGS__ )
#define APP_STORAGE_WARNING_PRINT(format, ...) tcx_WriteLog(UDP_STORAGE_MODULE, LOG_LEVEL_WARNING, format, ##__VA_ARGS__ )
#define APP_STORAGE_ERROR_PRINT(format, ...) tcx_WriteLog(UDP_STORAGE_MODULE, LOG_LEVEL_ERROR, format, ##__VA_ARGS__ )
#define APP_STORAGE_RT_PRINT(format, ...) tcx_WriteLog(UDP_STORAGE_MODULE, LOG_LEVEL_REAL_TIME, format, ##__VA_ARGS__ )
#define APP_STORAGE_PRINT_DATA(pu8_Buffer, u16_Length) tcx_WriteLogData(UDP_STORAGE_MODULE, LOG_LEVEL_INFO, pu8_Buffer, u16_Length)
/*******************************************
Defines
********************************************/
// socket configuration
#define STORAGE_SERVER_UDP_PORT 3550
#define UDP_RX_MSG_MAX_LEN ( 1024 * 9 )
#define UDP_TX_MSG_MAX_LEN ( 1024 * 9 )
#define UDP_PROTOCOL_TOKEN_LEN 25
/*******************************************
Types
********************************************/
/*******************************************
Locals
********************************************/
/*******************************************
Auxiliary functions
********************************************/
// returns true if the input strings are equal, false otherwise
static bool StringCmp(const u8 *pu8_Str1, const char *pu8_Str2, u32 u32_Len)
{
return (strncmp((const char *)pu8_Str1, pu8_Str2, u32_Len) == 0) ? TRUE : FALSE;
}
static s32 FileSize(const char *sFilename)
{
u32 rc = 0;
FILE *fp = fopen(sFilename, "r");
if ( fp )
{
fseek(fp, 0L, SEEK_END);
rc = ftell(fp);
fclose(fp);
}
else
{
APP_STORAGE_INFO_PRINT("ERROR could not open file %s\n", sFilename);
}
return rc;
}
static E_CMBS_RC FileWrite(const char *sFilename, u32 u32_DataLen, const u8 *pu8_Data)
{
E_CMBS_RC rc = CMBS_RC_ERROR_GENERAL;
FILE *fp = fopen(sFilename, "w");
if ( fp )
{
if ( fwrite(pu8_Data, sizeof(u8), u32_DataLen, fp) > 0 )
{
rc = CMBS_RC_OK;
}
else
{
APP_STORAGE_INFO_PRINT("ERROR fwrite failed\n");
}
fclose(fp);
}
else
{
APP_STORAGE_INFO_PRINT("ERROR could not open file %s\n", sFilename);
}
return rc;
}
static E_CMBS_RC FileRead(const char *sFilename, u32 *pu32_DataLen, u8 *pu8_Data)
{
E_CMBS_RC rc = CMBS_RC_ERROR_GENERAL;
s32 s32_Filesize, num_of_bytes_read=0;
FILE *fp;
*pu32_DataLen = 0;
s32_Filesize = FileSize(sFilename);
fp = fopen(sFilename, "r");
if ( fp && s32_Filesize > 0)
{
num_of_bytes_read = fread(pu8_Data, sizeof(u8), s32_Filesize, fp);
if ( num_of_bytes_read > 0 )
{
*pu32_DataLen = num_of_bytes_read;
rc = CMBS_RC_OK;
}
else
{
APP_STORAGE_INFO_PRINT("ERROR fread failed\n");
}
}
else
{
APP_STORAGE_INFO_PRINT("ERROR could not open file %s\n", sFilename);
}
if(fp)
{
fclose(fp);
}
return rc;
}
static bool FileExist(const char *sFilename)
{
bool rc = FALSE;
FILE *fp = fopen(sFilename, "r");
if ( fp )
{
rc = TRUE;
fclose(fp);
}
return rc;
}
// handle RX messages
static void HandleMsg(const u8 *u8_RxData, u8 *u8_TxData, u32 *pu32_TxLen)
{
// UDP API definition
// ==============
// STORE <filename> <length decimal> <data raw binary>
// Response: STORE OK <filename> / STORE NOK <filename>
//
// LOAD <filename>
// Response: LOAD OK <filename> <length decimal> <data raw binary> / LOAD NOK <filename>
char sCmd[UDP_PROTOCOL_TOKEN_LEN], sFilename[UDP_PROTOCOL_TOKEN_LEN];
u32 u32_RxPos, u32_Bytes;
*pu32_TxLen = 0;
// read command
sscanf((const char *)u8_RxData, "%s %n ", sCmd, &u32_Bytes);
u32_RxPos = u32_Bytes;
if ( StringCmp((u8*)sCmd, "STORE", strlen("STORE")) )
{
u32 u32_DataLen;
E_CMBS_RC rc;
// read filename
sscanf((const char *)u8_RxData + u32_RxPos, "%s %n ", sFilename, &u32_Bytes);
u32_RxPos += u32_Bytes;
// read data len
sscanf((const char *)u8_RxData + u32_RxPos, "%u %n ", &u32_DataLen, &u32_Bytes);
u32_RxPos += u32_Bytes;
// write to file
rc = FileWrite(sFilename, u32_DataLen, u8_RxData + u32_RxPos);
// write response
*pu32_TxLen = sprintf((char*)u8_TxData, "%s", "STORE ");
if ( rc == CMBS_RC_OK )
{
*pu32_TxLen += sprintf((char*)u8_TxData + *pu32_TxLen, "%s", "OK ");
}
else
{
*pu32_TxLen += sprintf((char*)u8_TxData + *pu32_TxLen, "%s", "NOK ");
}
*pu32_TxLen += sprintf((char*)u8_TxData + *pu32_TxLen, "%s", sFilename);
}
else if ( StringCmp((u8*)sCmd, "LOAD", strlen("LOAD")) )
{
u32 u32_RawDataLen;
// read filename
sscanf((const char *)u8_RxData + u32_RxPos, "%s %n ", sFilename, &u32_Bytes);
u32_RxPos += u32_Bytes;
// write response
*pu32_TxLen = sprintf((char*)u8_TxData, "%s", "LOAD ");
if ( FileExist(sFilename) )
{
*pu32_TxLen += sprintf((char*)u8_TxData + *pu32_TxLen, "%s %s %u ", "OK ", sFilename, FileSize(sFilename));
// read file
FileRead(sFilename, &u32_RawDataLen, u8_TxData + *pu32_TxLen);
*pu32_TxLen += u32_RawDataLen;
}
else
{
*pu32_TxLen += sprintf((char*)u8_TxData + *pu32_TxLen, "%s %s", "NOK ", sFilename);
}
}
else
{
APP_STORAGE_INFO_PRINT("Unknown command %s ignored", sCmd);
}
}
// handles recieved messages
#ifdef WIN32
static DWORD WINAPI UDPStorageThread(LPVOID lpParam)
#else
static void* UDPStorageThread(void *arg)
#endif
{
u8 u8_RxData[UDP_RX_MSG_MAX_LEN];
u8 u8_TxData[UDP_TX_MSG_MAX_LEN];
u32 u32_TxLen;
// create UDP socket and listen
#ifdef WIN32
SOCKET s;
struct sockaddr_in server, si_other;
int slen, recv_len;
WSADATA wsa;
slen = sizeof(si_other);
// Initialize winsock
APP_STORAGE_INFO_PRINT("\nInitialising Winsock...");
if ( WSAStartup(MAKEWORD(2, 2), &wsa) != 0 )
{
APP_STORAGE_INFO_PRINT("Failed. Error Code : %d", WSAGetLastError());
exit(EXIT_FAILURE);
}
APP_STORAGE_INFO_PRINT("Initialized.\n");
// Create a socket
if ( (s = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET )
{
APP_STORAGE_INFO_PRINT("Could not create socket : %d", WSAGetLastError());
}
APP_STORAGE_INFO_PRINT("Socket created.\n");
// Prepare the sockaddr_in structure
memset(&server, 0, sizeof(server));
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(STORAGE_SERVER_UDP_PORT);
// Bind
if ( bind(s, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR )
{
APP_STORAGE_INFO_PRINT("Bind failed with error code : %d", WSAGetLastError());
exit(EXIT_FAILURE);
}
puts("Bind done");
// keep listening for data
while (1)
{
APP_STORAGE_INFO_PRINT("Waiting for data...");
fflush(stdout);
// clear the buffer by filling null, it might have previously received data
memset(u8_RxData, '\0', sizeof(u8_RxData));
// try to receive some data, this is a blocking call
if ( (recv_len = recvfrom(s, u8_RxData, sizeof(u8_RxData), 0, (struct sockaddr *)&si_other, &slen)) == SOCKET_ERROR )
{
APP_STORAGE_INFO_PRINT("recvfrom() failed with error code : %d", WSAGetLastError());
exit(EXIT_FAILURE);
}
// print details of the client/peer and the data received
APP_STORAGE_INFO_PRINT("Received packet from %s:%d\n", inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port));
HandleMsg(u8_RxData, u8_TxData, &u32_TxLen);
// now reply the client
if ( sendto(s, u8_TxData, u32_TxLen, 0, (struct sockaddr *)&si_other, slen) == SOCKET_ERROR )
{
APP_STORAGE_INFO_PRINT("sendto() failed with error code : %d", WSAGetLastError());
exit(EXIT_FAILURE);
}
}
closesocket(s);
WSACleanup();
#else
int sockfd;
struct sockaddr_in servaddr,cliaddr;
socklen_t len;
UNUSED_PARAMETER(arg);
sockfd = socket(AF_INET,SOCK_DGRAM,0);
if(sockfd<0)
{
APP_STORAGE_INFO_PRINT("hanServer Error bind \n\n ");
exit(1);
}
bzero(& servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(STORAGE_SERVER_UDP_PORT);
if (bind(sockfd, (struct sockaddr *)&servaddr,sizeof(servaddr)) == -1 )
{
APP_STORAGE_INFO_PRINT("Bind failed with error code");
close(sockfd);
exit(1);
}
while ( 1 )
{
len = sizeof(cliaddr);
if ( recvfrom(sockfd, u8_RxData, sizeof(u8_RxData), 0, (struct sockaddr *)&cliaddr, &len) == -1 )
{
APP_STORAGE_INFO_PRINT("recvfrom() failed with error code");
close(sockfd);
exit(1);
}
HandleMsg(u8_RxData, u8_TxData, &u32_TxLen);
if(sendto(sockfd, u8_TxData, u32_TxLen, 0, (struct sockaddr *)&cliaddr, sizeof(cliaddr)) < 0)
{
APP_STORAGE_INFO_PRINT("sendto() failed with error code");
close(sockfd);
exit(1);
}
}
#endif
return 0;
}
/*******************************************
Storage Server protocol Mgr API
********************************************/
E_CMBS_RC UDPStorageMgr_Init(void)
{
// simply spawn UDP thread
#ifdef WIN32
DWORD dwThreadId;
CreateThread(
NULL, // default security attributes
0, // use default stack size
UDPStorageThread, // thread function name
0, // argument to thread function
0, // use default creation flags
&dwThreadId); // returns the thread identifier
if ( dwThreadId == 0 )
{
APP_STORAGE_INFO_PRINT("ERROR could not create thread!! ");
ExitProcess(3);
}
#else
int err;
pthread_t tid;
DECT_DBG("start thread UDPStorageThread...\n");
err = pthread_create(&tid, NULL, UDPStorageThread, NULL);
if ( err != 0 )
{
APP_STORAGE_INFO_PRINT("ERROR could not create thread!! ");
}
else
{
pthread_join(tid,NULL);
}
#endif
return CMBS_RC_OK;
}
//************* [End of file] ******************************************************************

View File

@@ -0,0 +1,43 @@
/*************************************************************************************************************
*** UDP Storage server
**
**************************************************************************************************************/
#ifndef __UDP_STORAGE_SRVR_H__
#define __UDP_STORAGE_SRVR_H__
// UDP API definition
// ==============
// STORE <filename> <length decimal> <data raw binary>
// Response: STORE OK <filename> / STORE NOK <filename>
//
// LOAD <filename>
// Response: LOAD OK <filename> <length decimal> <data raw binary> / LOAD NOK <filename>
/*******************************************
Includes
********************************************/
#include "cmbs_api.h"
/*******************************************
Defines
********************************************/
/*******************************************
Types
********************************************/
/*******************************************
Globals
********************************************/
/*******************************************
Storage Mgr API
********************************************/
E_CMBS_RC UDPStorageMgr_Init(void);
#endif /* __UDP_STORAGE_SRVR_H__ */
//************* [End of file] ******************************************************************

View File

@@ -0,0 +1,550 @@
/*!
* \file appSmartVoiceService.c
* \brief handle ULE internal PBX
* \Author moria
*
*
*******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "cmbs_api.h"
#include "appcall.h"
#include "cmbs_voipline.h"
#include "appCallRouter.h"
#include "tcx_hostlog.h"
#include "appCallRouter.h"
#include "appAvsService.h"
#include "cmbs_han.h"
#include "appHanMw.h"
#include "apphan.h"
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
#define APPSMARTVOICE_MAX_NUM_CALLS 10
#define APPSMARTVOICE_NO_CALL APPSMARTVOICE_MAX_NUM_CALLS
#define APPSMARTVOICE_NO_FREE_SLOTS 0xFFFFFFFF
u32 appSmartVoiceSrv_appID = 3; /* Holds appID of the current app*/
ST_SMARTVOICE_CALL_DATA G_st_SMARTVOICE_CallData[APPSMARTVOICE_MAX_NUM_CALLS];
//Forward declarations for CB functions
EXTAPP_RC appSmartVoice_OnCallEstablish(IN u32 cmbsCallID, IN const char* calledID, IN const char* callerHandset, IN u32 lineID, IN EXTVOIP_CODEC* codecList, IN u32 codecListLength);
EXTAPP_RC appSmartVoice_OnMergeCallResponse(IN u32 cmbsCallID);
EXTAPP_RC appSmartVoice_OnMediaChange(u32 u32_CallID, EXTVOIP_CODEC e_Codec);
EXTAPP_RC appSmartVoice_SetAudioChannel (IN u32 cmbsCallID, IN u32 mediaChannelID, IN EXTVOIP_CODEC codec);
void appSmartVoice_UpdateCallState(IN u32 cmbsCallID, IN EXTVOIP_CALL_STATE e_CallState);
u8 appSmartVoice_AssignNewCallId(void);
EXTAPP_RC appSmartVoice_OnCallRelease(IN u32 cmbsCallID, IN EXTVOIP_RELEASE_REASON releaseReason);
u32 appSmartVoice_OnDivertCall(ST_DIVERT_CALL_INFO *pst_DivertCallInfo);
EXTAPP_RC appSmartVoice_OnCallAnswer(IN u32 u32_cmbsCallID, IN EXTVOIP_CODEC codec);
EXTAPP_RC LoadSmartVoiceService (void)
{
u8 u8_Idx;
EXTAPP_RC res;
ST_APP_FNC_TABLE st_AppTable;
memset(&st_AppTable,0x00,sizeof(ST_APP_FNC_TABLE));
st_AppTable.fncSetupCall = appSmartVoice_OnCallEstablish;
st_AppTable.fncDisconnectCall = appSmartVoice_OnCallRelease;
st_AppTable.fncMediaChange = appSmartVoice_OnMediaChange;
st_AppTable.fncSetAudioChannel = appSmartVoice_SetAudioChannel;
st_AppTable.fncUpdateCallState = appSmartVoice_UpdateCallState;
st_AppTable.fncDivertOutgoingCall = appSmartVoice_OnDivertCall;
st_AppTable.fncAnswerCall = appSmartVoice_OnCallAnswer;
st_AppTable.LineName[0] = 0;
for (u8_Idx = 0; u8_Idx < APPSMARTVOICE_MAX_NUM_CALLS; u8_Idx++)
{
G_st_SMARTVOICE_CallData[u8_Idx].e_Call = E_APPCMBS_CALL_CLOSE;
G_st_SMARTVOICE_CallData[u8_Idx].e_Media = E_APPCMBS_MEDIA_CLOSE;
g_u32_CallChannelIDMap[u8_Idx] = APPSMARTVOICE_NO_FREE_SLOTS;
}
res = AppCallRouter_AppInit(appSmartVoiceSrv_appID, &st_AppTable);
return res;
}
u8 appSmartVoice_AssignNewCallId(void)
{
u8 u8_Idx;
for (u8_Idx = 0; u8_Idx < APPSMARTVOICE_MAX_NUM_CALLS; u8_Idx++)
{
if(G_st_SMARTVOICE_CallData[u8_Idx].e_Call == E_APPCMBS_CALL_CLOSE)
break;
}
return u8_Idx;
}
u8 appSmartVoice_GetCallId(IN u32 cmbsCallID)
{
u8 u8_Idx;
for (u8_Idx = 0; u8_Idx < APPSMARTVOICE_MAX_NUM_CALLS; u8_Idx++)
{
if(G_st_SMARTVOICE_CallData[u8_Idx].u32_CmbsCallId == cmbsCallID && G_st_SMARTVOICE_CallData[u8_Idx].e_Call != E_APPCMBS_CALL_CLOSE)
break;
}
return u8_Idx;
}
void appSmartVoice_UpdateCallState(IN u32 cmbsCallID, IN EXTVOIP_CALL_STATE e_CallState)
{
u8 u8_CallId = appSmartVoice_GetCallId(cmbsCallID);
if (u8_CallId == APPSMARTVOICE_NO_CALL)
{
printf("\n appSmartVoice_UpdateCallState: Invalid call id \n");
}
else
G_st_SMARTVOICE_CallData[u8_CallId].e_Call = e_CallState;
return;
}
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
EXTAPP_RC appSmartVoice_OnCallEstablish(IN u32 cmbsCallID, IN const char* calledID, IN const char* callerHandset, IN u32 lineID, IN EXTVOIP_CODEC* codecList, IN u32 codecListLength)
{
PST_SMARTVOICE_CALL_DATA pst_CallData;
ST_APPCALL_PROPERTIES st_Properties;
u8 u8_CallId = appSmartVoice_AssignNewCallId();
if (u8_CallId == APPSMARTVOICE_NO_CALL)
{
printf("\n appSmartVoice_OnCallEstablish: Error \n");
return EXTAPP_RC_FAIL;
}
pst_CallData = &G_st_SMARTVOICE_CallData[u8_CallId];
pst_CallData->u32_CmbsCallId = cmbsCallID;
printf("\n<<<<<< appSmartVoice_OnCallEstablish >>>>>>>\n");
if(!codecListLength)
pst_CallData->e_Codec = EXTVOIP_CODEC_PCM_LINEAR_NB;
else
pst_CallData->e_Codec = codecList[0];
extvoip_GetChannelSlotsForCall(cmbsCallID, pst_CallData->e_Codec, &(pst_CallData->u32_ChannelParameter));
pst_CallData->e_Media = E_APPCMBS_MEDIA_PEND;
//st_Properties.e_IE = CMBS_IE_CALLPROGRESS;
// st_Properties.psz_Value = "CMBS_CALL_PROGR_SETUP_ACK\0";
// appcall_ProgressCall(&st_Properties, 1, (u16)cmbsCallID, NULL);
st_Properties.e_IE = CMBS_IE_CALLPROGRESS;
st_Properties.psz_Value = "CMBS_CALL_PROGR_PROCEEDING\0";
appcall_ProgressCall(&st_Properties, 1, (u16)cmbsCallID, NULL);
// TBD: Establish channel to S2/IOT with call id, slots
pst_CallData->e_Call = E_APPCMBS_CALL_OUT_PROC;
strncpy(G_st_SMARTVOICE_CallData[u8_CallId].ch_CalledID, calledID, strlen(calledID));
return EXTAPP_RC_OK;
}
EXTAPP_RC appSmartVoice_OnCallRelease(IN u32 cmbsCallID, IN EXTVOIP_RELEASE_REASON releaseReason)
{
u8 u8_CallId = appSmartVoice_GetCallId(cmbsCallID);
if (u8_CallId == APPSMARTVOICE_NO_CALL)
{
printf("\n appSmartVoice_OnCallRelease: Call released \n");
return EXTAPP_RC_FAIL;
}
if (extvoip_CallMediaStop(cmbsCallID))
{
extvoip_FreeSlotsForCall(cmbsCallID,&(G_st_SMARTVOICE_CallData[u8_CallId].u32_ChannelParameter));
G_st_SMARTVOICE_CallData[u8_CallId].e_Call = E_APPCMBS_CALL_CLOSE;
G_st_SMARTVOICE_CallData[u8_CallId].e_Media = E_APPCMBS_MEDIA_PEND;
memset(G_st_SMARTVOICE_CallData[u8_CallId].ch_CalledID,'\0',sizeof(char)*CALL_PARTICIPANT_ID_MAX_LEN);
}
return EXTAPP_RC_OK;
}
//Hanserver/S2 application should invoke this API after contact resolution
u32 appSmartVoice_CallContact(u32 u32_CallId, char * CalledPartyName, char * psz_Digits)
{
u32 u32_ActiveCallID = AppCallRouter_DivertOutgoingCall(u32_CallId, CalledPartyName, psz_Digits) ;
return u32_ActiveCallID;
}
EXTAPP_RC appSmartVoice_OnMediaChange(u32 u32_CallID, EXTVOIP_CODEC e_Codec)
{
PST_CALL_OBJ pst_Call = _appcall_CallObjGetById(u32_CallID);
if(pst_Call)
{
// answer current call
extvoip_OnAnswerCall(u32_CallID, e_Codec);
if (extvoip_CallMediaStart(u32_CallID, (u16)(pst_Call->u32_ChannelParameter)) == TRUE)
{
return EXTAPP_RC_OK;
}
else
{
printf("\n appSmartVoice_OnMediaChange: ERROR \n ");
return EXTAPP_RC_FAIL;
}
}
else
{
printf("\n appSmartVoice_OnMediaChange: Invalid Call Id \n ");
return EXTAPP_RC_FAIL;
}
}
EXTAPP_RC appSmartVoice_SetAudioChannel (IN u32 cmbsCallID, IN u32 mediaChannelID, IN EXTVOIP_CODEC e_Codec)
{
u8 u8_CallId = appSmartVoice_GetCallId(cmbsCallID);
char ch_Param[CALL_PARTICIPANT_ID_MAX_LEN];
if (u8_CallId == APPSMARTVOICE_NO_CALL)
{
printf("\n appSmartVoice_SetAudioChannel: Error \n");
return EXTAPP_RC_FAIL;
}
G_st_SMARTVOICE_CallData[u8_CallId].u32_ChannelID = mediaChannelID;
// answer current call
extvoip_OnAnswerCall(cmbsCallID, e_Codec);
if (extvoip_CallMediaStart(cmbsCallID, G_st_SMARTVOICE_CallData[u8_CallId].u32_ChannelParameter))
{
// p_AudioApp_AudioStart((u8)pst_Call->u32_ChannelID, (u8 *)pst_Call->ch_CallerID);
G_st_SMARTVOICE_CallData[u8_CallId].e_Media = E_APPCMBS_MEDIA_ACTIVE;
memcpy(ch_Param, &G_st_SMARTVOICE_CallData[u8_CallId].ch_CalledID[1], sizeof(G_st_SMARTVOICE_CallData[u8_CallId].ch_CalledID) - 1);
app_HanMWAudioStart(cmbsCallID, ch_Param);
appSmartVoice_AddToCallChannelMap(mediaChannelID, u8_CallId);
return EXTAPP_RC_OK;
}
else
{
printf("\n appSmartVoice_SetAudioChannel: ERROR \n ");
return EXTAPP_RC_FAIL;
}
}
u32 appSmartVoice_OnDivertCall(ST_DIVERT_CALL_INFO *pst_DivertCallInfo)
{
u32 u32_ActiveCmbsCallId;
ST_APPCALL_PROPERTIES st_Properties[7];
PST_CALL_OBJ pst_Call;
char psz_Codecs[CMBS_AUDIO_CODEC_MAX * 2] = { 0 };
if(!pst_DivertCallInfo)
{
printf("\n appSmartVoice_OnDivertCall: Error \n");
return EXTAPP_RC_FAIL;
}
u32_ActiveCmbsCallId = pst_DivertCallInfo->cmbsCallID;
// get call object
pst_Call = _appcall_CallObjGetById(u32_ActiveCmbsCallId);
if ( !pst_Call )
{
printf("appSmartVoice_OnDivertCall : NO SUCH CALL WITH ID %d\n", u32_ActiveCmbsCallId);
return EXTAPP_RC_FAIL;
}
if(pst_DivertCallInfo->u8_NumOfCodecs)
{
u8 u8_Idx = 0;
sprintf(psz_Codecs, "%d",pst_DivertCallInfo->pu8_CodecsList[u8_Idx++]);
while(u8_Idx != pst_DivertCallInfo->u8_NumOfCodecs)
{
u8 u8_Len = strlen(psz_Codecs);
char psz_Temp[5]={0,};
sprintf(psz_Temp, ",%d",pst_DivertCallInfo->pu8_CodecsList[u8_Idx++]);
strcat(&psz_Codecs[u8_Len],psz_Temp);
}
}
else
{
// put codecs priority (WB, NB)
sprintf(psz_Codecs, "%d,%d", (CMBS_AUDIO_CODEC_PCM_LINEAR_WB), (CMBS_AUDIO_CODEC_PCM_LINEAR_NB));
}
st_Properties[0].e_IE = CMBS_IE_CALLERPARTY;
st_Properties[0].psz_Value = pst_DivertCallInfo->psz_CalledDigits;
st_Properties[1].e_IE = CMBS_IE_CALLEDPARTY;
st_Properties[1].psz_Value = pst_DivertCallInfo->psz_CallerID;/*h1 for testing*/
st_Properties[2].e_IE = CMBS_IE_MEDIADESCRIPTOR;
st_Properties[2].psz_Value = psz_Codecs;
st_Properties[3].e_IE = CMBS_IE_CALLERNAME;
st_Properties[3].psz_Value = "SMARTVOICE",
st_Properties[4].e_IE = CMBS_IE_LINE_ID;
st_Properties[4].psz_Value = "1\0";
st_Properties[5].e_IE = CMBS_IE_MELODY;
st_Properties[5].psz_Value = "1\0";
st_Properties[6].e_IE = CMBS_IE_RECONNECT_CALL;
st_Properties[6].psz_Value = "1\0";
pst_DivertCallInfo->cmbsCallID = appcall_EstablishCall(st_Properties, 7);
if(_appcall_CallObjGetById(pst_DivertCallInfo->cmbsCallID))
{
u8 u8_CallId = appSmartVoice_AssignNewCallId();
if(u8_CallId != APPSMARTVOICE_NO_CALL)
{
G_st_SMARTVOICE_CallData[u8_CallId].u32_CmbsCallId = pst_DivertCallInfo->cmbsCallID;
G_st_SMARTVOICE_CallData[u8_CallId].u32_ChannelParameter = pst_DivertCallInfo->u32_ChannelParameter;
G_st_SMARTVOICE_CallData[u8_CallId].e_Media = E_APPCMBS_MEDIA_PEND;
G_st_SMARTVOICE_CallData[u8_CallId].e_Call= E_APPCMBS_CALL_OUT_PROC;
return EXTAPP_RC_OK;
}
else
{
printf("\appSmartVoice_OnDivertCall: unable to assign new Smart Voice callId\n");
return EXTAPP_RC_FAIL;
}
}
else
{
printf("\appSmartVoice_OnDivertCall: unable to divert call\n");
return EXTAPP_RC_FAIL;
}
appSmartVoice_AddToCallChannelMap(pst_DivertCallInfo->u32_ChannelID,u32_ActiveCmbsCallId);
return pst_DivertCallInfo->cmbsCallID;
}
EXTAPP_RC appSmartVoice_OnCallAnswer(IN u32 u32_cmbsCallID, IN EXTVOIP_CODEC codec)
{
u32 u32_ChannelSlots;
u8 u8_CallId = appSmartVoice_GetCallId(u32_cmbsCallID);
if(u8_CallId == APPSMARTVOICE_NO_CALL)
{
printf("\appSmartVoice_OnCallAnswer: Invalid call Id\n");
return EXTVOIP_RC_FAIL;
}
extvoip_GetChannelSlotsForCall(u32_cmbsCallID,codec,&u32_ChannelSlots);
G_st_SMARTVOICE_CallData[u8_CallId].u32_ChannelParameter = u32_ChannelSlots;
if(u32_ChannelSlots != APPSMARTVOICE_NO_FREE_SLOTS)
{
if(appmedia_CallObjMediaStart(0,u32_cmbsCallID,u32_ChannelSlots,NULL))
G_st_SMARTVOICE_CallData[u8_CallId].e_Media = E_APPCMBS_MEDIA_ACTIVE;
}
else
{
printf("\n appSmartVoice_OnCallAnswer: No free slots for call %d \n", u8_CallId);
}
return EXTAPP_RC_OK;
}
void appSmartVoice_AddToCallChannelMap(u32 u32_ChannelId, u32 u32_cmbsCallId)
{
//Add Channel ID against appropriate call ID
g_u32_CallChannelIDMap[u32_cmbsCallId] = u32_ChannelId;
}
u32 appSmartVoice_GetCallIDfromChannelID(u32 u32_ChannelId)
{
u32 u32_CallID = 0xFFFF;
u8 u32_Index = 0;
//Get Call ID from Call ID and Channel ID map
for(u32_Index = 0;u32_Index < APPSMARTVOICE_MAX_NUM_CALLS; u32_Index++)
{
if(g_u32_CallChannelIDMap[u32_Index] == u32_ChannelId)
{
u32_CallID = u32_Index;
break;
}
}
return u32_CallID;
}
void appSmartVoice_ReleaseSmvCall(u32 u32_CallID)
{
//Release call for the call ID
extvoip_OnDisconnectCall(u32_CallID,EXTVOIP_REASON_NORMAL);
//Clear the channel call mapping
g_u32_CallChannelIDMap[u32_CallID] = APPSMARTVOICE_NO_FREE_SLOTS;
}
// Helper function to get Device ID from a string
static bool appSmv_ConvertDeviceIdFromStr(const u8 *pu8_Buffer, u16 *pu16_DeviceId)
{
u16 u16_DeviceId = 0;
u8 u8_DeviceIdNibbleStr, u8_Index, NumOfNibbles = sizeof(u16_DeviceId)*2;
for(u8_Index=0; u8_Index<NumOfNibbles; u8_Index++)
{
u8_DeviceIdNibbleStr = pu8_Buffer[u8_Index];
if (u8_DeviceIdNibbleStr >= '0' && u8_DeviceIdNibbleStr <= '9')
{
u16_DeviceId |= (u8_DeviceIdNibbleStr - '0') << (12 - u8_Index * 4);
}
else if (u8_DeviceIdNibbleStr >= 'A' && u8_DeviceIdNibbleStr <= 'F')
{
u16_DeviceId |= (u8_DeviceIdNibbleStr - 'A' + 0xA) << (12 - u8_Index * 4);
}
}
*pu16_DeviceId = u16_DeviceId;
return TRUE;
}
u8 appSmv_ConvertDeviceIdToStr(u16 u16_DeviceId, u8 *pu8_Buffer)
{
u8 u8_Index, u8_DeviceIdNibble = 0, NumOfNibbles = sizeof(u16_DeviceId)*2;
for(u8_Index=1; u8_Index<=NumOfNibbles; u8_Index++)
{
u8_DeviceIdNibble = u16_DeviceId & 0xF;
if (u8_DeviceIdNibble <= 9)
{
pu8_Buffer[NumOfNibbles-u8_Index] = u8_DeviceIdNibble + '0';
}
else if (u8_DeviceIdNibble >= 0xA && u8_DeviceIdNibble <= 0xF)
{
pu8_Buffer[NumOfNibbles-u8_Index] = u8_DeviceIdNibble + 'A' - 0xA;
}
u16_DeviceId >>= 4;
}
return NumOfNibbles;
}
static bool appSmv_ConvertUnitIdFromStr(const u8 *pu8_Buffer, u8 *pu8_UnitId)
{
u8 u8_UnitId = 0, u8_DeviceIdNibbleStr, u8_Index, NumOfNibbles = sizeof(u8_UnitId)*2;
for(u8_Index=0; u8_Index<NumOfNibbles; u8_Index++)
{
u8_DeviceIdNibbleStr = pu8_Buffer[u8_Index];
if (u8_DeviceIdNibbleStr >= '0' && u8_DeviceIdNibbleStr <= '9')
{
u8_UnitId |= (u8_DeviceIdNibbleStr - '0') << (4 - u8_Index * 4);
}
else if (u8_DeviceIdNibbleStr >= 'A' && u8_DeviceIdNibbleStr <= 'F')
{
u8_UnitId |= (u8_DeviceIdNibbleStr - 'A' + 0xA) << (4 - u8_Index * 4);
}
}
*pu8_UnitId = u8_UnitId;
return TRUE;
}
void appSmartVoice_MakeCall(u32 u32_ChannelId, const char* calledID)
{
//Find if Called ID belongs to Device
if (strlen(calledID) == 8 && calledID[0] == 'D')
{
u16 u16_DeviceId = 0;
u8 u8_UnitId = 1;
ST_HAN_VOICE_CALL_REQ_PARAMS st_CallReqParams;
st_CallReqParams.u32_FieldMask = 0;
//Parse the called ID to find Device and Unit IDs
appSmv_ConvertDeviceIdFromStr((const u8 *) &calledID[1], &u16_DeviceId);
if(calledID[5] == 'U')
{
appSmv_ConvertUnitIdFromStr((const u8 *) &calledID[6], &u8_UnitId);
}
//Send message to device
app_DsrHanVoiceCallReq(u16_DeviceId, u8_UnitId, &st_CallReqParams);
}
// If Handset
else if (strlen(calledID) == 2 && calledID[0] == 'h')
{
u32 u32_cmbsCallId;
char ch_CallerNum[30] = {0};
char ch_CallerName[30] = {0};
EXTVOIP_CODEC codecList[] = { EXTVOIP_CODEC_PCM_LINEAR_WB, EXTVOIP_CODEC_PCM_LINEAR_NB };
PST_SMARTVOICE_CALL_DATA pst_CallData;
//Establish call
extvoip_OnSetupCall(appSmartVoiceSrv_appID, 0, calledID, ch_CallerNum, ch_CallerName, codecList, sizeof(codecList)/sizeof(EXTVOIP_CODEC), (int *) &u32_cmbsCallId);
u8 u8_CallID = appSmartVoice_AssignNewCallId();
pst_CallData = &G_st_SMARTVOICE_CallData[u8_CallID];
pst_CallData->u32_CmbsCallId = u32_cmbsCallId;
pst_CallData->e_Call = E_APPCMBS_CALL_INC_RING;
appSmartVoice_AddToCallChannelMap(u32_ChannelId, u32_cmbsCallId);
}
}
void appSmartVoice_ReleaseCall(u32 u32_ChannelId)
{
u32 u32_CallID = appSmartVoice_GetCallIDfromChannelID(u32_ChannelId);
if (u32_CallID == APPSMARTVOICE_NO_CALL)
{
printf("\n appVoipService_AnswerCall: Error \n");
return;
}
extvoip_OnDisconnectCall(u32_CallID,EXTVOIP_REASON_NORMAL);
}
void appSmartVioce_DisplayString(PST_APPCALL_PROPERTIES pst_Properties, int n_Properties, u32 u32_ChannelId, char *psz_Display)
{
//Get call ID from channel ID
u32 u32_CallID = appSmartVoice_GetCallIDfromChannelID(u32_ChannelId);
appcall_DisplayString(pst_Properties, 1, (u16) u32_CallID, NULL);
}

View File

@@ -0,0 +1,40 @@
/*!
* \file appSmartVoiceService.h
* \brief
* \Author DSPG
*
* @(#) %filespec: appSmartVoiceService.h
*
*******************************************************************************/
// register callbacks
EXTAPP_RC LoadSmartVoiceService(void);
typedef struct
{
u32 u32_CmbsCallId; /*!< Call Instance to identify the call on CMBS */
ST_IE_CALLERPARTY st_CallerParty; /*!< Caller Party, incoming call CLI, outgoing call Handset number */
ST_IE_CALLEDPARTY st_CalledParty; /*!< Called Party, incoming call ringing mask, outgoing call to be dialled number */
char ch_CallerID[CALL_PARTICIPANT_ID_MAX_LEN]; /*!< buffer of caller party number */
char ch_CalledID[CALL_PARTICIPANT_ID_MAX_LEN]; /*!< buffer of called party number */
u32 u32_ChannelID; /*!< Channel ID to identify the media connection on CMBS */
u32 u32_ChannelParameter; /*!< Channel Parameter provides information about the parameter settings, e.g. IOM - used slots */
EXTVOIP_CODEC e_Codec; /*!< used codec */
u8 pu8_CodecsList[EXTVOIP_CODEC_MAX]; /*!< Codecs list */
u8 u8_CodecsLength; /*!< Codecs list length */
E_APPCMBS_CALL e_Call; /*!< call state */
E_APPCMBS_MEDIA e_Media; /*!< media entity state */
bool b_Incoming; /*!< TRUE for incoming calls, FALSE o/w */
} ST_SMARTVOICE_CALL_DATA, * PST_SMARTVOICE_CALL_DATA;
u32 g_u32_CallChannelIDMap[10];
void appSmartVoice_AddToCallChannelMap(u32 u32_ChannelID, u32 u32_CallID);
u32 appSmartVoice_CallContact(u32 u32_ChannelID, char * CalledPartyName, char * psz_Digits);
void appSmartVoice_ReleaseCall(u32 u32_cmbsCallID);
u32 appSmartVoice_GetCallIDfromChannelID(u32 u32_ChannelID);
void appSmartVoice_MakeCall(u32 u32_ChannelID, const char* calledID);
void appSmartVoice_ReleaseSmvCall(u32 u32_cmbsCallID);
void appSmartVioce_DisplayString(PST_APPCALL_PROPERTIES pst_Properties, int n_Properties, u32 u32_ChannelID, char *psz_Display);

View File

@@ -0,0 +1,287 @@
#include "cmbs_voipline.h"
#include "appCallRouter.h"
#include "ListsApp.h"
#include "string.h"
#include "stdlib.h"
#define APP_ROUTER_INFO_PRINT(format, ...) tcx_WriteLog(ROUTER_MODULE, LOG_LEVEL_INFO, format, ##__VA_ARGS__ )
#define APP_ROUTER_ERROR_PRINT(format, ...) tcx_WriteLog(ROUTER_MODULE, LOG_LEVEL_ERROR, format, ##__VA_ARGS__ )
#define APP_ROUTER_NO_APP 0xFFFFFFFF
ST_APP_FNC_TABLE g_st_AppTable[MAX_NUM_OF_APPS];
u32 g_u32_AppCallIDMap[APPCALL_CALLOBJ_MAX];
u32 AppCallRouter_GetAppForCallDivert(char *psz_Digits);
ST_CMBS_ROUTE_TABLE g_st_cmbs_route_table[MAX_NUM_OF_APPS] = {
/* app_id line_start max_line HS_Num Device_id digits ListenInCall*/
{3, -1, -1, NULL, NULL, "@", NULL }, //Smart Voice app
{5, -1, -1, NULL, NULL, "**", NULL }, //ULE internal PBX, ** route call via voice routing table
{5, -1, -1, NULL, NULL, "h*", "@" },
{5, -1, -1, NULL, NULL, "D*", "@" },
{5, -1, -1, NULL, "D*", NULL, NULL },
{0, 0, 0, "h*", "D*", "ANY", "@" } //Voipline app, default handler for call
};
// ========== CallRouter_Init ===========
/*!
\brief Callback function of all registered apps being called
\param[in] None
\return None
*/
void AppCallRouter_Init (void)
{
int index;
for(index = 0; index < APPCALL_CALLOBJ_MAX; index++)
g_u32_AppCallIDMap[index] = APP_ROUTER_NO_APP;
memset(g_st_AppTable, 0, sizeof(g_st_AppTable));
}
u8 AppCallRouter_AppInit (u32 u32_AppId, ST_APP_FNC_TABLE *pst_AppTable)
{
int i;
for (i=0;i<MAX_NUM_OF_APPS;i++)
{
if ((g_st_cmbs_route_table[i].u32_AppId == u32_AppId) && (g_st_cmbs_route_table[i].u32_AppId < MAX_NUM_OF_APPS))
{
APP_ROUTER_INFO_PRINT("g_st_AppTable %d 0x%x\n",i,g_st_AppTable[i]);
memcpy (&g_st_AppTable[g_st_cmbs_route_table[i].u32_AppId], pst_AppTable, sizeof(ST_APP_FNC_TABLE));
return EXTAPP_RC_OK;
}
}
return EXTAPP_RC_FAIL;
}
// ========== CallRouter_AppSelection ===========
/*!
\brief Selects matching app based on the condition provided in the ST_CMBS_ROUTE_TABLE
\param[in] u32_CallID CallID from CMBS
\param[in] psz_CalledId pointer parameter buffer
\param[in] psz_CallerHandset pointer parameter buffer
\param[in] u32_LineId expected lineID
\return < EXTAPP_RC >
*/
EXTAPP_RC AppCallRouter_AppSelection(IN u32 u32_CallID, IN const char* psz_CalledId, IN const char* psz_CallerHandset, IN u32 u32_LineId)
{
int i=0;
char input[50];
int res=-1;
printf("\n\n CallRouter_AppSelection \n");
for (i=0;i<MAX_NUM_OF_APPS;i++)
{
if (NULL == g_st_AppTable[g_st_cmbs_route_table[i].u32_AppId].fncSetupCall )
continue;
APP_ROUTER_INFO_PRINT("%s %d HS/D %s line %d\n",__FUNCTION__,i,psz_CallerHandset,u32_LineId);
if ( ((g_st_cmbs_route_table[i].u32_StartLineId != -1) && (g_st_cmbs_route_table[i].u32_MaxLineId != -1)) && ((u32_LineId >= g_st_cmbs_route_table[i].u32_StartLineId) && (u32_LineId<=g_st_cmbs_route_table[i].u32_MaxLineId)) )
{
APP_ROUTER_INFO_PRINT("\n -> line MAtching AppID %d %d\n",g_u32_AppCallIDMap[u32_CallID],g_st_cmbs_route_table[i].u32_AppId);
res = AppCallRouter_MakeCall(u32_CallID , g_st_cmbs_route_table[i].u32_AppId);
if(res != EXTAPP_RC_OK)
continue;
else
{
AppCallRouter_AddToAppCallMap(u32_CallID,g_st_cmbs_route_table[i].u32_AppId);
return EXTAPP_RC_OK;
}
}
if(psz_CallerHandset[0] == 'D')
{
if (g_st_cmbs_route_table[i].psz_DeviceId &&
((strcmp("D*",g_st_cmbs_route_table[i].psz_DeviceId) == 0) || (strcmp(psz_CallerHandset,g_st_cmbs_route_table[i].psz_DeviceId) == 0)))
{
APP_ROUTER_INFO_PRINT("\n -> Dev MAtching AppID %d %d\n",g_u32_AppCallIDMap[u32_CallID],g_st_cmbs_route_table[i].u32_AppId);
res = AppCallRouter_MakeCall(u32_CallID,g_st_cmbs_route_table[i].u32_AppId);
if(res != EXTAPP_RC_OK)
continue;
else
{
AppCallRouter_AddToAppCallMap(u32_CallID,g_st_cmbs_route_table[i].u32_AppId);
return EXTAPP_RC_OK;
}
}
}
else
{
sprintf(input,"H%s",psz_CallerHandset);
if(g_st_cmbs_route_table[i].psz_HandsetNum &&
((strcmp("H*",g_st_cmbs_route_table[i].psz_HandsetNum) == 0) || (strcmp(g_st_cmbs_route_table[i].psz_HandsetNum,input) == 0)))
{
APP_ROUTER_INFO_PRINT("\n -> HS MAtching AppID %d %d\n",g_u32_AppCallIDMap[u32_CallID],g_st_cmbs_route_table[i].u32_AppId);
res = AppCallRouter_MakeCall(u32_CallID,g_st_cmbs_route_table[i].u32_AppId);
if(res != EXTAPP_RC_OK)
continue;
else
{
AppCallRouter_AddToAppCallMap(u32_CallID,g_st_cmbs_route_table[i].u32_AppId);
return EXTAPP_RC_OK;
}
}
}
if((g_st_cmbs_route_table[i].psz_Digits && strcmp(psz_CalledId, g_st_cmbs_route_table[i].psz_Digits) == 0 ) ||
((g_st_cmbs_route_table[i].u32_AppId == 3) && (psz_CalledId[0] == g_st_cmbs_route_table[i].psz_Digits[0])))
{
APP_ROUTER_INFO_PRINT("\n -> Dig MAtching AppID %d %d\n",g_u32_AppCallIDMap[u32_CallID],g_st_cmbs_route_table[i].u32_AppId);
res = AppCallRouter_MakeCall(u32_CallID,g_st_cmbs_route_table[i].u32_AppId);
if(res != EXTAPP_RC_OK)
continue;
else
{
AppCallRouter_AddToAppCallMap(u32_CallID,g_st_cmbs_route_table[i].u32_AppId);
return EXTAPP_RC_OK;
}
}
}
APP_ROUTER_ERROR_PRINT("\n -> NOT MAtching with App cond, call id %d\n", u32_CallID);
return EXTAPP_RC_FAIL;
}
// ========== AppCallRouter_MakeCall ===========
/*!
\brief Calls the Setup Call API of the selected App
\param[in] u32_CallID CallID from CMBS
\return < EXTVOIP_RC >
*/
EXTVOIP_RC AppCallRouter_MakeCall(u32 u32_CallID, u32 u32_AppId)
{
PST_CALL_OBJ pstCall;
EXTVOIP_RC rc = CMBS_RC_OK;
EXTVOIP_CODEC codecs[CMBS_AUDIO_CODEC_MAX] = {0};
if ((u32_AppId == -1) || (u32_AppId >= MAX_NUM_OF_APPS))
return EXTVOIP_RC_FAIL;
// get call object
pstCall = _appcall_CallObjGetById(u32_CallID);
if(!pstCall)
return EXTVOIP_RC_FAIL;
// make codecs list
if(pstCall->u8_CodecsLength)
{
int i = 0;
for(i=0;i<pstCall->u8_CodecsLength;i++)
codecs[i] = cmbsCodec2VoipCodec(pstCall->pu8_CodecsList[i]);
}
APP_ROUTER_INFO_PRINT("\n CallRouter_MakeCall %d 0x%x\n",u32_AppId,(unsigned int *)(g_st_AppTable[u32_AppId]).fncSetupCall);
// call SetupCall function
if((g_st_AppTable[u32_AppId]).fncSetupCall)
rc = ((g_st_AppTable[u32_AppId]).fncSetupCall)(u32_CallID, pstCall->ch_CalledID, pstCall->ch_CallerID, pstCall->u8_LineId, codecs, pstCall->u8_CodecsLength);
if(rc != EXTVOIP_RC_OK)
return EXTVOIP_RC_FAIL;
return EXTVOIP_RC_OK;
}
void AppCallRouter_AddToAppCallMap(u32 u32_CallID, u32 u32_AppId)
{
if(u32_CallID < APPCALL_CALLOBJ_MAX)
g_u32_AppCallIDMap[u32_CallID] = u32_AppId;
return;
}
u32 AppCallRouter_DivertOutgoingCall( u32 u32_CallId, char *CalledPartyName, char *psz_Digits )
{
u32 u32_AppId, u32_ActiveCallID;
char psz_CallerID[CALL_PARTICIPANT_ID_MAX_LEN] = {0,};
EXTAPP_RC rc = EXTAPP_RC_FAIL;
ST_DIVERT_CALL_INFO st_DivertCallInfo = {0,};
EXTVOIP_CODEC codecs[EXTVOIP_CODEC_MAX] = {0};
PST_CALL_OBJ pst_ActiveCall = _appcall_CallObjGetById(u32_CallId);
if(!pst_ActiveCall)
{
printf("\n AppCallRouter_DivertOutgoingCall: Error");
return rc;
}
u32_AppId = AppCallRouter_GetAppForCallDivert(psz_Digits /*, u32_LineId*/);
if (u32_AppId == MAX_NUM_OF_APPS)
{
printf("AppCallRouter_DivertOutgoingCall: No App for Call Divert");
return rc;
}
// make codecs list
if(pst_ActiveCall->u8_CodecsLength)
{
int i = 0;
for(i=0;i<pst_ActiveCall->u8_CodecsLength;i++)
codecs[i] = cmbsCodec2VoipCodec(pst_ActiveCall->pu8_CodecsList[i]);
}
st_DivertCallInfo.cmbsCallID = u32_CallId;
st_DivertCallInfo.psz_CalledID = CalledPartyName;
st_DivertCallInfo.psz_CalledDigits = psz_Digits;
if(pst_ActiveCall->ch_CallerID[0] != 'D')
{
psz_CallerID[0]='h';
strcpy(psz_CallerID+1,pst_ActiveCall->ch_CallerID);
st_DivertCallInfo.psz_CallerID = psz_CallerID;
}
else
{
st_DivertCallInfo.psz_CallerID = pst_ActiveCall->ch_CallerID;
}
st_DivertCallInfo.u32_LineId = pst_ActiveCall->u8_LineId;
st_DivertCallInfo.pu8_CodecsList = codecs;
st_DivertCallInfo.u8_NumOfCodecs = pst_ActiveCall->u8_CodecsLength;
u32_ActiveCallID = g_st_AppTable[u32_AppId].fncDivertOutgoingCall(&st_DivertCallInfo);
if(rc == EXTAPP_RC_OK)
AppCallRouter_AddToAppCallMap(st_DivertCallInfo.cmbsCallID,u32_AppId);
return u32_ActiveCallID;
}
u32 AppCallRouter_GetAppForCallDivert(char *psz_Digits)
{
int i;
for(i=0;i<MAX_NUM_OF_APPS;i++)
{
if(psz_Digits && g_st_cmbs_route_table[i].psz_Digits)
{
if (((psz_Digits[0] == 'D') && (strcmp("D*", g_st_cmbs_route_table[i].psz_Digits) == 0 )) ||
((psz_Digits[0] == 'h') && (strcmp("h*", g_st_cmbs_route_table[i].psz_Digits) == 0 )) ||
(strcmp(psz_Digits,g_st_cmbs_route_table[i].psz_Digits) == 0) ||
((psz_Digits[0] != 'D') && (psz_Digits[0] != 'h') && (strcmp("ANY", g_st_cmbs_route_table[i].psz_Digits) == 0))
)
return g_st_cmbs_route_table[i].u32_AppId;
}
}
return MAX_NUM_OF_APPS;
}

View File

@@ -0,0 +1,188 @@
#ifndef APPCALLROUTER
#define APPCALLROUTER
#include "cmbs_voip_api.h"
#include "ListsApp.h"
#define MAX_NUM_OF_APPS 6
typedef enum
{
EXTAPP_RC_OK,
EXTAPP_RC_FAIL
} EXTAPP_RC;
typedef struct
{
u32 cmbsCallID;
char *psz_CallerID;
char *psz_CalledID;
char *psz_CalledDigits;
u16 u16_HsNum;
u16 u16_DeviceId;
u32 u32_LineId;
EXTVOIP_CODEC *pu8_CodecsList;
u8 u8_NumOfCodecs;
u32 u32_ChannelID; /*!< Channel ID to identify the media connection on CMBS */
u32 u32_ChannelParameter; /*!< Channel Parameter provides information about the parameter settings, e.g. IOM - used slots */
}ST_DIVERT_CALL_INFO;
// Make a call
typedef EXTAPP_RC (*app_SetupCallFunc)(IN u32 cmbsCallID, IN const char* calledID, IN const char* callerHandset, IN u32 lineID, IN EXTVOIP_CODEC* codecList, IN u32 codecListLength);
// Proceeding
typedef EXTAPP_RC (*app_ProceedingCallFunc)(IN u32 cmbsCallID);
// Alerting
typedef EXTAPP_RC (*app_AlertingCallFunc)(IN u32 cmbsCallID);
// Answer call
typedef EXTAPP_RC (*app_AnswerCallFunc)(IN u32 cmbsCallID, IN EXTVOIP_CODEC codec);
// Release active call
typedef EXTAPP_RC (*app_DisconnectCallFunc)(IN u32 cmbsCallID, IN EXTVOIP_RELEASE_REASON disconnectReason);
// Release active call ack
typedef EXTAPP_RC (*app_DisconnectCallDoneFunc)(IN u32 cmbsCallID);
// Hold call
typedef EXTAPP_RC (*app_HoldCallFunc)(IN u32 cmbsCallID);
// Hold call ack
typedef EXTAPP_RC (*app_HoldCallAckFunc)(IN u32 cmbsCallID);
// Resume call
typedef EXTAPP_RC (*app_ResumeCallFunc)(IN u32 cmbsCallID);
// Resume call ack
typedef EXTAPP_RC (*app_ResumeCallAckFunc)(IN u32 cmbsCallID);
// Conference call
typedef EXTAPP_RC (*app_ConferenceCallFunc)(IN u32 cmbsCallID, IN u32 cmbsCallID2);
// Change codec
typedef EXTAPP_RC (*app_MediaChangeFunc)(IN u32 cmbsCallID, IN EXTVOIP_CODEC codec);
// Change codec ack
typedef EXTAPP_RC (*app_MediaChangeAckFunc)(IN u32 cmbsCallID, IN EXTVOIP_CODEC codec);
// Send digits
typedef EXTAPP_RC (*app_SendDigitsCallFunc)(IN u32 cmbsCallID, IN char* digits);
// Merge call response
typedef EXTAPP_RC (*app_MergeCallResFunc)(IN u32 cmbsCallID);
/*
* Helpers
*/
// Retrieve call caller id
typedef EXTAPP_RC (*app_GetCallerIDFunc)(IN u32 cmbsCallID, OUT char* callerID);
// Retrieve call called id
typedef EXTAPP_RC (*app_GetCalledIDFunc)(IN u32 cmbsCallID, OUT char* calledID);
/*
* Audio config
*/
// Set audio channel
typedef EXTAPP_RC (*app_SetAudioChannelFunc)(IN u32 cmbsCallID, IN u32 mediaChannelID, IN EXTVOIP_CODEC codec);
/*
* Contacts sync
*/
// Retrieve contacts size
typedef u32 (*app_GetContactsCountFunc)();
// Retrieve contact entry
typedef EXTAPP_RC (*app_GetContactEntryFunc)(IN u32 itemid, OUT char* firstName, OUT char* lastName, OUT char* number, OUT u32* isOnline);
//Divert outgoing call
typedef u32 (*app_DivertOutgoingCallFunc)(IN ST_DIVERT_CALL_INFO *pst_DivertCallInfo );
typedef void (*app_UpdateCallStateFunc)(IN u32 cmbsCallID, IN EXTVOIP_CALL_STATE e_CallState);
typedef struct app_FnTable_s
{
// line ID
//u32 LineID;
char LineName[LIST_NAME_MAX_LEN];
// function for call setup
app_SetupCallFunc fncSetupCall;
// function for call proceeding
app_ProceedingCallFunc fncProceedingCall;
// function for call proceeding
app_AlertingCallFunc fncAlertingCall;
// function for call answer
app_AnswerCallFunc fncAnswerCall;
// function for call disconnect
app_DisconnectCallFunc fncDisconnectCall;
// function for call disconnect done
app_DisconnectCallDoneFunc fncDisconnectCallDone;
// function for call hold
app_HoldCallFunc fncHoldCall;
// function for call hold acknowledge
app_HoldCallAckFunc fncHoldCallDone;
// function for call resume
app_ResumeCallFunc fncResumeCall;
// function for call conference
app_ConferenceCallFunc fncConferenceCall;
// function for call resume acknowledge
app_ResumeCallAckFunc fncResumeCallDone;
// function for call codec change
app_MediaChangeFunc fncMediaChange;
// function for call codec change acknowledge
app_MediaChangeAckFunc fncMediaChangeAck;
// function to send digits
app_SendDigitsCallFunc fncSendDigits;
// function to retrieve caller ID
app_GetCallerIDFunc fncGetCallerID;
// function to retrieve called ID
app_GetCalledIDFunc fncGetCalledID;
// function to set audio channel
app_SetAudioChannelFunc fncSetAudioChannel;
// function to retrieve cotacts size
app_GetContactsCountFunc fncContactsCount;
// function to retrieve contact entry
app_GetContactEntryFunc fncContactsEntry;
// function for merge call response
app_MergeCallResFunc fncMergeCallRes;
// function to Divert Outgoing Calls
app_DivertOutgoingCallFunc fncDivertOutgoingCall;
// function to update call state
app_UpdateCallStateFunc fncUpdateCallState;
} ST_APP_FNC_TABLE;
typedef struct
{
u32 u32_AppId;
u32 u32_StartLineId;
u32 u32_MaxLineId;
const char *psz_HandsetNum;
const char *psz_DeviceId;
const char *psz_Digits;
const char *psz_ListenInCall;
}ST_CMBS_ROUTE_TABLE;
void AppCallRouter_Init (void);
void AppCallRouter_AddToAppCallMap(u32 u32_CallID, u32 u32_AppId);
EXTAPP_RC AppCallRouter_AppSelection(IN u32 u32_CallID, IN const char* psz_CalledId, IN const char* psz_CallerHandset, IN u32 u32_LineId);
u8 AppCallRouter_AppInit (u32 u32_AppId, ST_APP_FNC_TABLE *pst_AppTable);
EXTVOIP_RC AppCallRouter_MakeCall(u32 u32_CallID, u32 u32_AppId);
EXTAPP_RC AppCallRouter_AnswerCall(u32 u32_CallID);
u32 AppCallRouter_DivertOutgoingCall( u32 u32_CallId, char *CalledPartyName, char *psz_Digits );
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,210 @@
/*!
* \file appHanMW.h
* \brief HAN MW API
* \author HAN Team
*
*
*******************************************************************************/
#if !defined( _APPHANMW_H )
#define _APPHANMW_H
#include "cmbs_han.h"
#include "appcall.h"
E_CMBS_RC app_HanMwMsgSend_ImplicitLinkSetup (u16 u16_RequestId, u16 u16_DestDeviceId, ST_IE_HAN_MSG_CTL* pst_HANMsgCtl , ST_IE_HAN_MSG * pst_HANMsg );
E_CMBS_RC app_HanMwRawMsgSend_ImplicitLinkSetup (u16 u16_RequestId, u16 u16_DestDeviceId, ST_IE_HAN_MSG_CTL* pst_HANMsgCtl , ST_IE_DATA * pst_RawMsg );
void app_HanMWDeleteDeviceViaQueue(u16 u16_deviceId, bool b_BlackList);
void app_HanMWInitialize(void);
void app_HanMWReleaseLinkRequest(u16 u16_deviceId);
void app_HanMWHwVersionGet(void);
void app_HanMWSwVersionGet(void);
void app_HanMWGetNumOfFunMsgInQ(u16 u16_deviceId);
void app_HanMWClearFunMsgQ(u16 u16_deviceId);
void app_HanMWGetMaxNumOfDevices(void);
void app_HanMWGetNumOfRegDevices(void);
void app_HanMWOnMergeCallsResponse(ST_IE_RESPONSE st_Response, u16 u16_CallId, u8 *pu8_FirstParticipant, u8 *pu8_SecondParticipant);
void app_HanMWOnCallReleaseResponse(u16 u16_CallId);
void app_HanMWReleaseCall(u16 u16_CallId);
void app_HanMWOnCallReleaseInd(u16 u16_CallId);
void app_HanMWOnCallEstablishInd(u16 u16_CallId, u8 *pu8_Participant);
void app_HanMWOnDeviceReleasedFromCall(u16 u16_CallId, u16 u16_DeviceId);
void app_HanMWOnHsReleasedFromCall(u16 u16_CallId, u8 u8_HsNum);
void app_HanMWDivertCall(u32 u32_ChannelId, char *pNum, char *pName);
void app_HanMWAudioStart(u32 u32_AudioLineId, char *pParam);
void app_HanMwGetActiveCallsInfo(void);
void app_HanMwSmvCallRelease(u32 u32_ChannelId);
void app_HanMwAudioStart(u32 u32_ChannelId);
void app_HanMWAudioStop(u32 u32_ChannelId);
void app_HanMWAudioEnd(u32 u32_ChannelId);
void app_HanMwAudioProgress(u32 u32_ChannelId);
void app_HanMwQueryEnd(u32 u32_ChannelId);
void app_HanMwMakeCall(u32 u32_ChannelId, char *CalledId);
void app_HanMWOnActiveCallsInfoGetRes(ST_ALLACTIVECALLSINFO st_AllActiveCalls);
void app_HanMwOnSmvCallReleaseRes(u32 u32_ChannelId);
void app_HanMWOnAudioStart(u32 u32_ChannelId, const u8 *pu8_DevUnitID);
void app_HanMWOnAudioStop(const u8 *pu8_DevUnitID);
void app_HanMWOnAudioEnd(const u8 *pu8_DevUnitID);
void app_HanMWSetNEMoMode(char *pMode);
void app_HanMWOnSetNEMoModeRes(bool b_status);
void app_HanMWFirmwareUpdateStart(char *pFileName,u32 u32_PacketSize,u32 u32_RestoreParam);
void app_HanMWOnFirmwareUpdateStartRes(bool b_status);
void app_HanMWOnFirmwareUpdateEndRes(bool b_status);
void app_HanMWOnTargetUpSetDefaults(void);
void app_HanMWDataCallRelease(u8 u8_SessionId);
void app_HanMWDataCallSend(u8 u8_SessionId, u16 u16_DataLen, u8* pu8_Data);
void app_HanMWOnDataCallSendRes(u8 u8_SessionId, u8 u8_Status);
void app_HanMWOnDataCallReleaseInd(u8 u8_SessionId, u8 u8_Status);
void app_HanMWOnDataCallSessionCreatedInd(u16 u16_AppId, u8 u8_SessionId, u16 u16_DeviceId);
void app_HanMWOnDataCallReceivedDataInd(u8 u8_SessionId, u16 u16_DataLen, u8* pu8_Data);
typedef void (*t_fptrHANClientOnRegClosed)( E_CMBS_EVENT_ID , void * );
typedef void (*t_fptrHANClientOnReadDeviceTableRes)( void * );
typedef void (*t_fptrHANClientOnReadDeviceSubInfoRes)( void * );
typedef u32 (*t_fptrHANClientOnMsgRecv)( void * , ST_IE_HAN_MSG *);
typedef u32 (*t_fptrHANClientOnDeviceFullDeleted)( u16, ST_IE_RESPONSE, u16 );
typedef u32 (*t_fptrHANClientOnDeviceRegistered)( u16 );
typedef u32 (*t_fptrHANClientOnDevicePartialDeleted)( u16 );
typedef u32(*t_fptrHANClientOnOpenRegRes)(int);
typedef u32(*t_fptrHANClientOnCloseRegRes)(int);
typedef u32(*t_fptrHANClientOnHandsetRegistered)(u8);
typedef u32(*t_fptrHANClientOnTargetUpIndication)();
typedef u32(*t_fptrHANClientOnEepParamGetRes)(bool, u8 *, u16,u8 *);
typedef u32(*t_fptrHANClientOnEepParamSetRes)(bool, u8 *);
typedef u32(*t_fptrHANClientOnEepAreaGetRes)(bool, u32, u16, u8 *);
typedef u32(*t_fptrHANClientOnEepAreaSetRes)(bool);
typedef u32(*t_fptrHANClientOnProdParamGetRes)(bool, u8 *, u16,u8 *);
typedef u32(*t_fptrHANClientOnProdParamSetRes)(bool, u8 *);
typedef u32(*t_fptrHANClientOnRamAreaGetRes)(bool, u32, u16, u8 *);
typedef u32(*t_fptrHANClientOnRamAreaSetRes)(bool);
typedef u32(*t_fptrHANClientOnEepromSizeGetRes)(bool, u32);
typedef u32(*t_fptrHANClientOnHwVersionGetRes)(bool, u8 *, u8 *, u8 *, u8 *);
typedef u32(*t_fptrHANClientOnSwVersionGetRes)(bool, u16, u16, u16, u16);
typedef u32(*t_fptrHANClientOnGetNumOfFunMsgInQRes)(bool, u16, u8, u8);
typedef u32(*t_fptrHANClientOnMessageSendRes)(bool, u16);
typedef void (*t_fptrHANClientOnReadDeviceTablePhase2Res)( void * );
typedef void (*t_fptrHANClientOnReadDeviceSubInfoPhase2Res)( void * );
typedef void (*t_fptrHANClientOnReadBlackListDeviceTableRes)( void * );
typedef u32 (*t_fptrHANClientOnDeviceDeleted)( u16 );
typedef u32(*t_fptrHANClientOnRawMsgRecv)( void * , ST_IE_DATA *);
typedef u32(*t_fptrHANClientOnRawMessageSendRes)(bool, u16);
typedef u32(*t_fptrHANClientOnGetNumOfRegDevicesRes)(u16);
typedef u32(*t_fptrHANClientOnGetMaxNumOfDevicesRes)(u16);
typedef u32(*t_fptrHANClientOnMergeCallsRes)(bool, u16, u8 *, u8 *);
typedef u32(*t_fptrHANClientOnCallReleaseResponse)(u16);
typedef u32(*t_fptrHANClientOnCallReleaseInd)(u16);
typedef u32(*t_fptrHANClientOnCallEstablishInd)(u16, u8 *);
typedef u32(*t_fptrHANClientOnDeviceReleasedFromCall)(u16, u16);
typedef u32(*t_fptrHANClientOnHsReleasedFromCall)(u16, u8);
typedef void(*t_fptrHANClientOnActiveCallsInfoGetRes)(ST_ALLACTIVECALLSINFO);
typedef void(*t_fptrHANClientOnDataCallSendRes)(u8 , u8 );
typedef void(*t_fptrHANClientOnDataCallReleaseInd)(u8, u8);
typedef void(*t_fptrHANClientOnDataCallSessionCreatedInd)(u16, u8, u16);
typedef void(*t_fptrHANClientOnDataCallReceivedDataInd)(u8, u16, u8*);
typedef void(*t_fptrHANClientOnSetNEMoModeRes)(bool);
typedef void(*t_fptrHANClientOnFirmwareUpdateStartRes)(bool);
typedef void(*t_fptrHANClientOnFirmwareUpdateEndRes)(bool);
typedef void(*t_fptrHANClientOnSmvCallReleaseRes)(u16);
typedef void(*t_fptrHANClientOnAudioStart)(u32 , const u8 *);
typedef void(*t_fptrHANClientOnAudioStop)(const u8 *);
typedef void(*t_fptrHANClientOnAudioEnd)(const u8 *);
typedef u32(*t_fptrHANClientOnDivertCallRes)(u32);
typedef struct s_fptrHanClient
{
t_fptrHANClientOnRegClosed g_fptrHANClientOnRegClosed;
t_fptrHANClientOnReadDeviceTableRes g_fptrHANClientOnReadDeviceTableRes;
t_fptrHANClientOnReadDeviceSubInfoRes g_fptrHANClientOnReadDeviceSubInfoRes;
t_fptrHANClientOnMsgRecv g_fptrHANClientOnMsgRecv;
t_fptrHANClientOnDeviceFullDeleted g_fptrHANClientOnDeviceFullDeleted;
t_fptrHANClientOnDeviceRegistered g_fptrHANClientOnDeviceRegistered;
t_fptrHANClientOnDevicePartialDeleted g_fptrHANClientOnDevicePartialDeleted;
t_fptrHANClientOnOpenRegRes g_fptrHANClientOnOpenRegRes;
t_fptrHANClientOnCloseRegRes g_fptrHANClientOnCloseRegRes;
t_fptrHANClientOnHandsetRegistered g_fptrHANClientOnHandsetRegistered;
t_fptrHANClientOnTargetUpIndication g_fptrHANClientOnTargetUpIndication;
t_fptrHANClientOnEepParamGetRes g_fptrHANClientOnEepParamGetRes;
t_fptrHANClientOnEepParamSetRes g_fptrHANClientOnEepParamSetRes;
t_fptrHANClientOnEepAreaGetRes g_fptrHANClientOnEepAreaGetRes;
t_fptrHANClientOnEepAreaSetRes g_fptrHANClientOnEepAreaSetRes;
t_fptrHANClientOnProdParamGetRes g_fptrHANClientOnProdParamGetRes;
t_fptrHANClientOnProdParamSetRes g_fptrHANClientOnProdParamSetRes;
t_fptrHANClientOnRamAreaGetRes g_fptrHANClientOnRamAreaGetRes;
t_fptrHANClientOnRamAreaSetRes g_fptrHANClientOnRamAreaSetRes;
t_fptrHANClientOnEepromSizeGetRes g_fptrHANClientOnEepromSizeGetRes;
t_fptrHANClientOnHwVersionGetRes g_fptrHANClientOnHwVersionGetRes;
t_fptrHANClientOnSwVersionGetRes g_fptrHANClientOnSwVersionGetRes;
t_fptrHANClientOnGetNumOfFunMsgInQRes g_fptrHANClientOnGetNumOfFunMsgInQRes;
t_fptrHANClientOnMessageSendRes g_fptrHANClientOnMessageSendRes;
t_fptrHANClientOnReadDeviceTablePhase2Res g_fptrHANClientOnReadDeviceTablePhase2Res;
t_fptrHANClientOnReadDeviceSubInfoPhase2Res g_fptrHANClientOnReadDeviceSubInfoPhase2Res;
t_fptrHANClientOnReadBlackListDeviceTableRes g_fptrHANClientOnReadBlackListDeviceTable;
t_fptrHANClientOnDeviceDeleted g_fptrHANClientOnDeviceDeleted ;
t_fptrHANClientOnRawMsgRecv g_fptrHANClientOnRawMsgRecv;
t_fptrHANClientOnRawMessageSendRes g_fptrHANClientOnRawMessageSendRes;
t_fptrHANClientOnGetNumOfRegDevicesRes g_fptrHANClientOnGetNumOfRegDevicesRes;
t_fptrHANClientOnGetMaxNumOfDevicesRes g_fptrHANClientOnGetMaxNumOfDevicesRes;
t_fptrHANClientOnMergeCallsRes g_fptrHANClientOnMergeCallsRes;
t_fptrHANClientOnCallReleaseResponse g_fptrHANClientOnCallReleaseResponse;
t_fptrHANClientOnCallReleaseInd g_fptrHANClientOnCallReleaseInd;
t_fptrHANClientOnCallEstablishInd g_fptrHANClientOnCallEstablishInd;
t_fptrHANClientOnDeviceReleasedFromCall g_fptrHANClientOnDeviceReleasedFromCall;
t_fptrHANClientOnHsReleasedFromCall g_fptrHANClientOnHsReleasedFromCall;
t_fptrHANClientOnActiveCallsInfoGetRes g_fptrHANClientOnActiveCallsInfoGetRes;
t_fptrHANClientOnDataCallSendRes g_fptrHANClientOnDataCallSendRes;
t_fptrHANClientOnDataCallReleaseInd g_fptrHANClientOnDataCallReleaseInd;
t_fptrHANClientOnDataCallSessionCreatedInd g_fptrHANClientOnDataCallSessionCreatedInd;
t_fptrHANClientOnDataCallReceivedDataInd g_fptrHANClientOnDataCallReceivedDataInd;
t_fptrHANClientOnSetNEMoModeRes g_fptrHANClientOnSetNEMoModeRes;
t_fptrHANClientOnFirmwareUpdateStartRes g_fptrHANClientOnFirmwareUpdateStartRes;
t_fptrHANClientOnFirmwareUpdateEndRes g_fptrHANClientOnFirmwareUpdateEndRes;
t_fptrHANClientOnSmvCallReleaseRes g_fptrHANClientOnSmvCallReleaseRes;
t_fptrHANClientOnAudioStart g_fptrHANClientOnAudioStart;
t_fptrHANClientOnAudioStop g_fptrHANClientOnAudioStop;
t_fptrHANClientOnAudioEnd g_fptrHANClientOnAudioEnd;
t_fptrHANClientOnDivertCallRes g_fptrHANClientOnDivertCallRes;
}s_fptrHanClient;
typedef void(*t_fptrHANServerOnTargetUpSetDefaults)(void);
typedef struct s_fptrHanServer
{
t_fptrHANServerOnTargetUpSetDefaults g_fptrHANServerOnTargetUpSetDefaults;
}s_fptrHanServer;
void app_HanMWRegisterCallBacks(s_fptrHanClient* HanClientRegisterCallBacks);
void app_HanMWRegisterServerCallBacks(s_fptrHanServer* HanServerRegisterCallBacks);
E_CMBS_RC app_HanMwDeviceReadTable (u16 u16_NumOfEntries, u16 u16_IndexOfFirstEntry, u8 isBrief);
E_CMBS_RC app_HanMwReadSingleDeviceRegistrationInformation(u16 u16_DeviceId);
E_CMBS_RC app_HanMwDeviceReadTablePhase2(u16 u16_NumOfEntries, u16 u16_IndexOfFirstEntry);
E_CMBS_RC app_HanMwReadSingleDeviceRegistrationInformationPhase2(u16 u16_DeviceId);
E_CMBS_RC app_HanMwDeviceReadBlackListTable (u16 u16_NumOfEntries, u16 u16_IndexOfFirstEntry);
typedef enum
{
NO_MSG_IN_QUEUE = 0,
FOUND_MSG_IN_QUEUE,
} E_MSG_IN_QUEUE_STATUS;
#endif // _APPHANMW_H
/**********************[End Of File]**********************************************************************************************************/

View File

@@ -0,0 +1,743 @@
/*!
* \file appUleIntPbx.c
* \brief handle ULE internal PBX
* \Author moria
*
*
*******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "appUleIntPbx.h"
#include "cmbs_api.h"
#include "cmbs_han.h"
#include "appcall.h"
#include "apphan.h"
#include "apphanvoicecallroutingtable.h"
#include "cmbs_voipline.h"
#include "tcx_hostlog.h"
#include "appAvsService.h"
#define APP_ULE_INX_PBX_INFO_PRINT(format, ...) tcx_WriteLog(ULE_INT_PBX, LOG_LEVEL_INFO, format, ##__VA_ARGS__ )
#define APP_ULE_INX_PBX_TRACE_PRINT(format, ...) tcx_WriteLog(ULE_INT_PBX, LOG_LEVEL_TRACE, format, ##__VA_ARGS__ )
#define APP_ULE_INX_PBX_WARNING_PRINT(format, ...) tcx_WriteLog(ULE_INT_PBX, LOG_LEVEL_WARNING, format, ##__VA_ARGS__ )
#define APP_ULE_INX_PBX_ERROR_PRINT(format, ...) tcx_WriteLog(ULE_INT_PBX, LOG_LEVEL_ERROR, format, ##__VA_ARGS__ )
#define APP_ULE_INX_PBX_RT_PRINT(format, ...) tcx_WriteLog(ULE_INT_PBX, LOG_LEVEL_REAL_TIME, format, ##__VA_ARGS__ )
#define APP_ULE_INX_PBX_PRINT_DATA(pu8_Buffer, u16_Length) tcx_WriteLogData(ULE_INT_PBX, LOG_LEVEL_INFO, pu8_Buffer, u16_Length)
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
#define APP_PBX_CALL_PPARTICIPANT_HS_LEN 2
#define APP_PBX_CALL_PPARTICIPANT_DEVICE_LEN 8
#define APP_PBX_CALL_PARTICIPANT_DEVICE_OFFSET 1
#define APP_PBX_CALL_PARTICIPANT_UNIT_OFFSET 6
#define APP_PBX_CALL_PARTICIPANT_HS_NUM_OFFSET 1
#define APP_PBX_DEVICE_IDENTIFIER_OFFSET 0
#define APP_PBX_UNIT_IDENTIFIER_OFFSET 5
#define APP_PBX_HS_IDENTIFIER_OFFSET 0
#define APP_PBX_DEVICE_IDENTIFIER 'D'
#define APP_PBX_UNIT_IDENTIFIER 'U'
#define APP_PBX_HS_IDENTIFIER 'h'
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
typedef struct
{
u32 u32_CallId1;
u32 u32_CallId2;
bool b_ConvertToInt;
}ST_CALL_MERGE_INFO;
#define MERGE_CALL_DB_SIZE 5
#define MERGE_CALL_INVALID_CALL_ID 0xFFFFFFFF
#define MERGE_CALL_INVALID_RECORD_ID 0xFF
ST_CALL_MERGE_INFO g_st_CallsPengingForMerge_DB[MERGE_CALL_DB_SIZE] = {{MERGE_CALL_INVALID_CALL_ID, MERGE_CALL_INVALID_CALL_ID, FALSE},
{MERGE_CALL_INVALID_CALL_ID, MERGE_CALL_INVALID_CALL_ID, FALSE},
{MERGE_CALL_INVALID_CALL_ID, MERGE_CALL_INVALID_CALL_ID, FALSE},
{MERGE_CALL_INVALID_CALL_ID, MERGE_CALL_INVALID_CALL_ID, FALSE},
{MERGE_CALL_INVALID_CALL_ID, MERGE_CALL_INVALID_CALL_ID, FALSE}};
bool G_b_IntPbx_CallDivert = FALSE;
EXTAPP_RC appUleIntPbx_SetAudioChannel (IN u32 cmbsCallID, IN u32 mediaChannelID, IN EXTVOIP_CODEC e_Codec);
extern E_APPCMBS_MEDIA _appcall_CallObjMediaGet(PST_CALL_OBJ pst_Call);
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
u8 apppbx_AllocPendingMergeEntry()
{
u8 u8_Index = 0;
for(u8_Index=0; u8_Index<MERGE_CALL_DB_SIZE; u8_Index++)
{
if(g_st_CallsPengingForMerge_DB[u8_Index].u32_CallId1 == MERGE_CALL_INVALID_CALL_ID &&
g_st_CallsPengingForMerge_DB[u8_Index].u32_CallId2 == MERGE_CALL_INVALID_CALL_ID)
{
APP_ULE_INX_PBX_TRACE_PRINT("apppbx_AllocPendingMergeEntry -> allocated entry %d\n", u8_Index);
return u8_Index;
}
}
return MERGE_CALL_INVALID_RECORD_ID;
}
u8 apppbx_FindPendingMergeEntry(u32 u32_CallId)
{
u8 u8_Index = 0;
for(u8_Index=0; u8_Index<MERGE_CALL_DB_SIZE; u8_Index++)
{
if(g_st_CallsPengingForMerge_DB[u8_Index].u32_CallId1 == u32_CallId ||
g_st_CallsPengingForMerge_DB[u8_Index].u32_CallId2 == u32_CallId)
{
APP_ULE_INX_PBX_TRACE_PRINT("apppbx_FindPendingMergeEntry -> entry %d\n", u8_Index);
return u8_Index;
}
}
return MERGE_CALL_INVALID_RECORD_ID;
}
bool apppbx_FreePendingMergeEntry(u32 u32_CallId)
{
u8 u8_Index = 0;
for(u8_Index=0; u8_Index<MERGE_CALL_DB_SIZE; u8_Index++)
{
if(g_st_CallsPengingForMerge_DB[u8_Index].u32_CallId1 == u32_CallId ||
g_st_CallsPengingForMerge_DB[u8_Index].u32_CallId2 == u32_CallId)
{
APP_ULE_INX_PBX_TRACE_PRINT("apppbx_FreePendingMergeEntry -> entry %d\n", u8_Index);
g_st_CallsPengingForMerge_DB[u8_Index].u32_CallId1 = MERGE_CALL_INVALID_CALL_ID;
g_st_CallsPengingForMerge_DB[u8_Index].u32_CallId2 = MERGE_CALL_INVALID_CALL_ID;
return TRUE;
}
}
return FALSE;
}
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
//Forward declarations for CB functions
EXTAPP_RC appUleIntPbx_OnCallEstablish(IN u32 cmbsCallID, IN const char* calledID, IN const char* callerHandset, IN u32 lineID, IN EXTVOIP_CODEC* codecList, IN u32 codecListLength);
EXTAPP_RC appUleIntPbx_OnCallAnswer(IN u32 cmbsCallID, IN EXTVOIP_CODEC codec);
EXTAPP_RC appUleIntPbx_OnMergeCallResponse(IN u32 cmbsCallID);
u32 appUleIntPbx_OnDivertCall(ST_DIVERT_CALL_INFO *pst_DivertCallInfo);
EXTAPP_RC appUleIntPbx_SendDigits(IN u32 u32_cmbsCallID, IN char* psz_Digits);
u32 UleIntPbx_appID = 5; /* Holds appID of the current app*/
EXTAPP_RC LoadUleIntPbx (void)
{
EXTVOIP_RC res;
ST_APP_FNC_TABLE st_AppTable;
st_AppTable.fncSetupCall = appUleIntPbx_OnCallEstablish;
st_AppTable.fncAnswerCall = appUleIntPbx_OnCallAnswer;
st_AppTable.fncMergeCallRes = appUleIntPbx_OnMergeCallResponse;
st_AppTable.fncProceedingCall = NULL;
st_AppTable.fncAlertingCall = NULL;
st_AppTable.fncDisconnectCall = NULL;
st_AppTable.fncDisconnectCallDone = NULL;
st_AppTable.fncHoldCall = NULL;
st_AppTable.fncHoldCallDone = NULL;
st_AppTable.fncResumeCall = NULL;
st_AppTable.fncConferenceCall = NULL;
st_AppTable.fncResumeCallDone = NULL;
st_AppTable.fncMediaChange = NULL;
st_AppTable.fncMediaChangeAck = NULL;
st_AppTable.fncSendDigits = appUleIntPbx_SendDigits;
st_AppTable.fncGetCallerID = NULL;
st_AppTable.fncGetCalledID = NULL;
st_AppTable.fncSetAudioChannel = NULL;
st_AppTable.fncContactsCount = NULL;
st_AppTable.fncContactsEntry = NULL;
st_AppTable.fncDivertOutgoingCall = appUleIntPbx_OnDivertCall;
st_AppTable.fncUpdateCallState = NULL;
st_AppTable.LineName[0] = 0;
res = AppCallRouter_AppInit(UleIntPbx_appID, &st_AppTable);
return res;
}
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
static bool apppbx_ConvertDeviceIdFromStr(const u8 *pu8_Buffer, u16 *pu16_DeviceId)
{
u16 u16_DeviceId = 0;
u8 u8_DeviceIdNibbleStr, u8_Index, NumOfNibbles = sizeof(u16_DeviceId)*2;
for(u8_Index=0; u8_Index<NumOfNibbles; u8_Index++)
{
u8_DeviceIdNibbleStr = pu8_Buffer[u8_Index];
if (u8_DeviceIdNibbleStr >= '0' && u8_DeviceIdNibbleStr <= '9')
{
u16_DeviceId |= (u8_DeviceIdNibbleStr - '0') << (12 - u8_Index * 4);
}
else if (u8_DeviceIdNibbleStr >= 'A' && u8_DeviceIdNibbleStr <= 'F')
{
u16_DeviceId |= (u8_DeviceIdNibbleStr - 'A' + 0xA) << (12 - u8_Index * 4);
}
}
*pu16_DeviceId = u16_DeviceId;
return TRUE;
}
static u8 apppbx_ConvertDeviceIdToStr(u16 u16_DeviceId, u8 *pu8_Buffer)
{
u8 u8_Index, u8_DeviceIdNibble = 0, NumOfNibbles = sizeof(u16_DeviceId)*2;
for(u8_Index=1; u8_Index<=NumOfNibbles; u8_Index++)
{
u8_DeviceIdNibble = u16_DeviceId & 0xF;
if (u8_DeviceIdNibble <= 9)
{
pu8_Buffer[NumOfNibbles-u8_Index] = u8_DeviceIdNibble + '0';
}
else if (u8_DeviceIdNibble >= 0xA && u8_DeviceIdNibble <= 0xF)
{
pu8_Buffer[NumOfNibbles-u8_Index] = u8_DeviceIdNibble + 'A' - 0xA;
}
u16_DeviceId >>= 4;
}
return NumOfNibbles;
}
static bool apppbx_ConvertUnitIdFromStr(const u8 *pu8_Buffer, u8 *pu8_UnitId)
{
u8 u8_UnitId = 0, u8_DeviceIdNibbleStr, u8_Index, NumOfNibbles = sizeof(u8_UnitId)*2;
for(u8_Index=0; u8_Index<NumOfNibbles; u8_Index++)
{
u8_DeviceIdNibbleStr = pu8_Buffer[u8_Index];
if (u8_DeviceIdNibbleStr >= '0' && u8_DeviceIdNibbleStr <= '9')
{
u8_UnitId |= (u8_DeviceIdNibbleStr - '0') << (4 - u8_Index * 4);
}
else if (u8_DeviceIdNibbleStr >= 'A' && u8_DeviceIdNibbleStr <= 'F')
{
u8_UnitId |= (u8_DeviceIdNibbleStr - 'A' + 0xA) << (4 - u8_Index * 4);
}
}
*pu8_UnitId = u8_UnitId;
return TRUE;
}
static u8 apppbx_ConvertUnitIdToStr(u8 u8_UnitId, u8 *pu8_Buffer)
{
u8 u8_Index, u8_UnitIdNibble = 0, NumOfNibbles = sizeof(u8_UnitId)*2;
for(u8_Index=1; u8_Index<=NumOfNibbles; u8_Index++)
{
u8_UnitIdNibble = u8_UnitId & 0xF;
if (u8_UnitIdNibble <= 9)
{
pu8_Buffer[NumOfNibbles - u8_Index] = u8_UnitIdNibble + '0';
}
else if (u8_UnitIdNibble >= 0xA && u8_UnitIdNibble <= 0xF)
{
pu8_Buffer[NumOfNibbles - u8_Index] = u8_UnitIdNibble + 'A' - 0xA;
}
u8_UnitId >>= 4;
}
return NumOfNibbles;
}
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
void appUleIntPbx_Call2HS(PST_CALL_OBJ pst_Call, u16 u16_DstId)
{
u32 u32_CallId;
EXTVOIP_RC en_Status = EXTVOIP_RC_FAIL;
//ST_APPCALL_PROPERTIES st_Properties = {0};
char ch_HsNum[30] = {0};
char ch_CallerNum[30] = {0};
char ch_CallerName[30] = {0};
u8 u8_EntryIndex;
u8 u8_LineId;
EXTVOIP_CODEC codecList[] = { EXTVOIP_CODEC_PCM_LINEAR_WB, EXTVOIP_CODEC_PCM_LINEAR_NB };
ch_HsNum[0] = 'h';
ch_HsNum[1] = (u8) u16_DstId + '0';
// alloc record in pending for merge DB
u8_EntryIndex = apppbx_AllocPendingMergeEntry();
if(u8_EntryIndex == MERGE_CALL_INVALID_RECORD_ID)
{
APP_ULE_INX_PBX_ERROR_PRINT("Cannot alloc record for merging call");
return;
}
g_st_CallsPengingForMerge_DB[u8_EntryIndex].u32_CallId1 = _appcall_CallObjIdGet(pst_Call);
if(!G_b_IntPbx_CallDivert)
{
memcpy(&ch_CallerNum[0], &pst_Call->ch_CallerID[0], pst_Call->st_CallerParty.u8_AddressLen );
u8_LineId = 0;
//send call progress
extvoip_OnProceedingCall(g_st_CallsPengingForMerge_DB[u8_EntryIndex].u32_CallId1);
// answer current call
extvoip_OnAnswerCall(g_st_CallsPengingForMerge_DB[u8_EntryIndex].u32_CallId1, EXTVOIP_CODEC_PCM_LINEAR_WB);
}
else
{
memcpy(&ch_CallerNum[0], &pst_Call->ch_CalledID[0], pst_Call->st_CalledParty.u8_AddressLen );
u8_LineId = 1;
}
en_Status = extvoip_OnSetupCall(UleIntPbx_appID, u8_LineId, ch_HsNum, ch_CallerNum, ch_CallerName, codecList, sizeof(codecList)/sizeof(EXTVOIP_CODEC), (int *) &u32_CallId);
if(en_Status == EXTVOIP_RC_OK)
{
g_st_CallsPengingForMerge_DB[u8_EntryIndex].u32_CallId2 = u32_CallId;
g_st_CallsPengingForMerge_DB[u8_EntryIndex].b_ConvertToInt = FALSE;
}
// merge calls will be invoked on call answer
}
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
EXTAPP_RC appUleIntPbx_OnCallEstablish(IN u32 cmbsCallID, IN const char* calledID, IN const char* callerHandset, IN u32 lineID, IN EXTVOIP_CODEC* codecList, IN u32 codecListLength)
{
PST_CALL_OBJ pst_CallPending = NULL;
PST_CALL_OBJ pst_Call = _appcall_CallObjGetById(cmbsCallID);
u8 u8_EntryIndex;
APP_ULE_INX_PBX_TRACE_PRINT("<<<<<< appUleIntPbx_OnCallEstablish >>>>>>>\n\n");
// make sure Caller Party Number is not empty
if(pst_Call)
{
// check whether a call is waiting for this HS/ device to be merged
pst_CallPending = appcall_GetCallPendingforDeviceObj(pst_Call);
if (pst_CallPending)
{
pst_CallPending->b_WaitingForMerge = FALSE;
// alloc record in pending for merge DB
u8_EntryIndex = apppbx_AllocPendingMergeEntry();
if(u8_EntryIndex == MERGE_CALL_INVALID_RECORD_ID)
{
APP_ULE_INX_PBX_ERROR_PRINT("Cannot alloc record for merging call");
return EXTAPP_RC_FAIL;
}
g_st_CallsPengingForMerge_DB[u8_EntryIndex].u32_CallId1 = _appcall_CallObjIdGet(pst_CallPending);
g_st_CallsPengingForMerge_DB[u8_EntryIndex].u32_CallId2 = cmbsCallID;
g_st_CallsPengingForMerge_DB[u8_EntryIndex].b_ConvertToInt = FALSE;
//Answer both calls
APP_ULE_INX_PBX_INFO_PRINT("Answer and merge calls: %d, %d\n",
g_st_CallsPengingForMerge_DB[u8_EntryIndex].u32_CallId1, g_st_CallsPengingForMerge_DB[u8_EntryIndex].u32_CallId2);
if(!G_b_IntPbx_CallDivert)
{
extvoip_OnAnswerCall(g_st_CallsPengingForMerge_DB[u8_EntryIndex].u32_CallId1, EXTVOIP_CODEC_PCM_LINEAR_WB); // current call
}
extvoip_OnAnswerCall(g_st_CallsPengingForMerge_DB[u8_EntryIndex].u32_CallId2, EXTVOIP_CODEC_PCM_LINEAR_WB); //pending call
if(!G_b_IntPbx_CallDivert)
{
// stop media channel
appmedia_CallObjMediaStop(pst_Call->u32_CallInstance, 0, NULL);
appmedia_CallObjMediaStop(pst_CallPending->u32_CallInstance, 0, NULL);
}
// merge calls
appcall_MergeCalls(g_st_CallsPengingForMerge_DB[u8_EntryIndex].u32_CallId1,
g_st_CallsPengingForMerge_DB[u8_EntryIndex].u32_CallId2,
g_st_CallsPengingForMerge_DB[u8_EntryIndex].b_ConvertToInt);
G_b_IntPbx_CallDivert = FALSE;
}
else
{
// check wether the calling device has specified the called party
if (strlen(calledID) == APP_PBX_CALL_PPARTICIPANT_DEVICE_LEN && calledID[APP_PBX_DEVICE_IDENTIFIER_OFFSET] == APP_PBX_DEVICE_IDENTIFIER)
{
u16 u16_DeviceId = 0;
u8 u8_UnitId = 1;
ST_HAN_VOICE_CALL_REQ_PARAMS st_CallReqParams;
apppbx_ConvertDeviceIdFromStr((const u8 *) &calledID[APP_PBX_CALL_PARTICIPANT_DEVICE_OFFSET], &u16_DeviceId);
if(calledID[APP_PBX_UNIT_IDENTIFIER_OFFSET] == APP_PBX_UNIT_IDENTIFIER)
{
apppbx_ConvertUnitIdFromStr((const u8 *) &calledID[APP_PBX_CALL_PARTICIPANT_UNIT_OFFSET], &u8_UnitId);
}
st_CallReqParams.u32_FieldMask = 0;
APP_ULE_INX_PBX_INFO_PRINT("Calling device has specified the called party - device#%d, unit %d\n", u16_DeviceId, u8_UnitId);
// Mark call as waiting to be merged
pst_Call->b_WaitingForMerge = TRUE;
// send FUN message to device requesting it to set up a call
app_DsrHanVoiceCallReq(u16_DeviceId, u8_UnitId, &st_CallReqParams);
}
else if (strlen(calledID) == APP_PBX_CALL_PPARTICIPANT_HS_LEN && calledID[APP_PBX_HS_IDENTIFIER_OFFSET] == APP_PBX_HS_IDENTIFIER)
{
u8 u8_HsNum = calledID[APP_PBX_CALL_PARTICIPANT_HS_NUM_OFFSET] - '0';
APP_ULE_INX_PBX_INFO_PRINT("Calling device has specified the called party - HS %d\n", u8_HsNum);
appUleIntPbx_Call2HS(pst_Call, u8_HsNum);
}
// valid called party was not specified by the calling party, later: handle HS number/ digits
else
{
u16 u16_DeviceId = 0;
u8 u8_UnitId = 1, u8_HsNum = 0;
bool b_MatchFound;
st_apphan_VoiceCallRoutingTableRecord st_VoiceCallRoutingTableRecord;
if (callerHandset[APP_PBX_DEVICE_IDENTIFIER_OFFSET] == APP_PBX_DEVICE_IDENTIFIER)
{
apppbx_ConvertDeviceIdFromStr((const u8 *) &callerHandset[APP_PBX_CALL_PARTICIPANT_DEVICE_OFFSET], &u16_DeviceId);
apppbx_ConvertUnitIdFromStr((const u8 *) &callerHandset[APP_PBX_CALL_PARTICIPANT_UNIT_OFFSET], &u8_UnitId);
APP_ULE_INX_PBX_INFO_PRINT("Calling device #%d, unit%d\n", u16_DeviceId, u8_UnitId);
// look for a match for device in Voice Call Routing Table
b_MatchFound = p_VoiceCallRoutingTable_FindMatchForDevice(u16_DeviceId, u8_UnitId, NULL, &st_VoiceCallRoutingTableRecord);
}
else
{
// Convert HS number from char to decimal
u8_HsNum = callerHandset[0] - '0';
APP_ULE_INX_PBX_INFO_PRINT("Calling HS #%d\n", u8_HsNum);
// look for a match for HS in Voice Call Routing Table
b_MatchFound = p_VoiceCallRoutingTable_FindMatchForHS(u8_HsNum, NULL, &st_VoiceCallRoutingTableRecord);
}
// look for a match for this device/ HS in audio routing table
if (b_MatchFound)
{
ST_HAN_VOICE_CALL_REQ_PARAMS st_CallReqParams;
st_CallReqParams.u32_FieldMask = 0;
APP_ULE_INX_PBX_INFO_PRINT("Found a match for Calling party number in Voice Call Routing Table\n");
// Mark call as waiting to be merged
pst_Call->b_WaitingForMerge = TRUE;
if(st_VoiceCallRoutingTableRecord.u8_DstType == DEVICE_ENTITY)
{
u8 u8_Len = 0;
pst_Call->st_CalledParty.u8_AddressLen = 0;
// send FUN "Make a Call" req to device
app_DsrHanVoiceCallReq(st_VoiceCallRoutingTableRecord.u16_DstId, st_VoiceCallRoutingTableRecord.u8_DstUnitId, &st_CallReqParams);
// store device and unit id as Called Party Number
pst_Call->st_CalledParty.pu8_Address[0] = APP_PBX_DEVICE_IDENTIFIER;
pst_Call->st_CalledParty.u8_AddressLen++;
u8_Len = apppbx_ConvertDeviceIdToStr(st_VoiceCallRoutingTableRecord.u16_DstId, &pst_Call->st_CalledParty.pu8_Address[1]);
pst_Call->st_CalledParty.u8_AddressLen += u8_Len;
pst_Call->st_CalledParty.pu8_Address[5] = APP_PBX_UNIT_IDENTIFIER;
pst_Call->st_CalledParty.u8_AddressLen++;
u8_Len = apppbx_ConvertUnitIdToStr(st_VoiceCallRoutingTableRecord.u8_DstUnitId, &pst_Call->st_CalledParty.pu8_Address[6]);
pst_Call->st_CalledParty.u8_AddressLen += u8_Len ;
}
// Destination is HS
else
{
appUleIntPbx_Call2HS(pst_Call, st_VoiceCallRoutingTableRecord.u16_DstId);
}
}
else
{
APP_ULE_INX_PBX_INFO_PRINT("Failed to find match for device in AudioRoutingTable for device#%d\n", u16_DeviceId != 0 ? u16_DeviceId : u8_HsNum);
}
}
}
}
else
{
APP_ULE_INX_PBX_ERROR_PRINT("Could not find call in appcall DB: call_id = %d \n", cmbsCallID);
}
return EXTAPP_RC_OK;
}
EXTAPP_RC appUleIntPbx_OnCallAnswer(IN u32 cmbsCallID, IN EXTVOIP_CODEC codec)
{
PST_CALL_OBJ pst_Call = _appcall_CallObjGetById(cmbsCallID);
u8 u8_EntryIndex = apppbx_FindPendingMergeEntry(cmbsCallID);
if(u8_EntryIndex != MERGE_CALL_INVALID_RECORD_ID)
{
//call divert from device to handset
if((cmbsCallID == g_st_CallsPengingForMerge_DB[u8_EntryIndex].u32_CallId1) &&
(_appcall_CallObjMediaGet(pst_Call) == E_APPCMBS_MEDIA_PEND))
{
u32 u32_ChannelSlots;
extvoip_GetChannelSlotsForCall(cmbsCallID,codec,&u32_ChannelSlots);
appmedia_CallObjMediaStart(0,cmbsCallID,u32_ChannelSlots,NULL);
}
else if ((cmbsCallID == g_st_CallsPengingForMerge_DB[u8_EntryIndex].u32_CallId2) &&
(_appcall_CallObjMediaGet(pst_Call) == E_APPCMBS_MEDIA_PEND))
{
//pst_Call = _appcall_CallObjGetById(g_st_CallsPengingForMerge_DB[u8_EntryIndex].u32_CallId1);
//appmedia_CallObjMediaStart(0,cmbsCallID,pst_Call->u32_ChannelParameter,NULL);
}
if ( (g_st_CallsPengingForMerge_DB[u8_EntryIndex].u32_CallId1 != MERGE_CALL_INVALID_RECORD_ID) &&
(g_st_CallsPengingForMerge_DB[u8_EntryIndex].u32_CallId2 != MERGE_CALL_INVALID_RECORD_ID) &&
(cmbsCallID == g_st_CallsPengingForMerge_DB[u8_EntryIndex].u32_CallId2))
{
PST_CALL_OBJ pst_Call1 = _appcall_CallObjGetById(g_st_CallsPengingForMerge_DB[u8_EntryIndex].u32_CallId1);
PST_CALL_OBJ pst_Call2 = _appcall_CallObjGetById(g_st_CallsPengingForMerge_DB[u8_EntryIndex].u32_CallId2);
// clear call pending
pst_Call1->b_WaitingForMerge = FALSE;
pst_Call2->b_WaitingForMerge = FALSE;
// stop media channel
//appmedia_CallObjMediaStop(pst_Call1->u32_CallInstance, 0, NULL);
//appmedia_CallObjMediaStop(pst_Call2->u32_CallInstance, 0, NULL);
appcall_MergeCalls(g_st_CallsPengingForMerge_DB[u8_EntryIndex].u32_CallId1,
g_st_CallsPengingForMerge_DB[u8_EntryIndex].u32_CallId2,
g_st_CallsPengingForMerge_DB[u8_EntryIndex].b_ConvertToInt);
if(G_b_IntPbx_CallDivert)
G_b_IntPbx_CallDivert = FALSE;
}
}
else
{ //call divert from device to device
if(G_b_IntPbx_CallDivert && (_appcall_CallObjMediaGet(pst_Call) == E_APPCMBS_MEDIA_PEND))
{
u32 u32_ChannelSlots;
extvoip_GetChannelSlotsForCall(cmbsCallID,codec,&u32_ChannelSlots);
appmedia_CallObjMediaStart(0,cmbsCallID,u32_ChannelSlots,NULL);
}
}
return EXTAPP_RC_OK;
}
EXTAPP_RC appUleIntPbx_OnMergeCallResponse(IN u32 cmbsCallID)
{
bool b_Status = apppbx_FreePendingMergeEntry(cmbsCallID);
return b_Status ? EXTAPP_RC_OK : EXTAPP_RC_FAIL;
}
u32 appUleIntPbx_OnDivertCall(ST_DIVERT_CALL_INFO *pst_DivertCallInfo)
{
PST_CALL_OBJ pst_Call = NULL;
ST_APPCALL_PROPERTIES st_Properties[7];
char psz_Codecs[CMBS_AUDIO_CODEC_MAX * 2] = { 0 };
if(pst_DivertCallInfo)
{
pst_Call = _appcall_CallObjGetById(pst_DivertCallInfo->cmbsCallID);
if(!pst_Call)
{
printf("\n appUleIntPbx_OnDivertCall:Error\n");
return EXTAPP_RC_FAIL;
}
}
else
{
printf("\n appUleIntPbx_OnDivertCall:Error\n");
return EXTAPP_RC_FAIL;
}
//Establish half call to caller device/HS
if(pst_DivertCallInfo->u8_NumOfCodecs)
{
u8 u8_Idx = 0;
sprintf(psz_Codecs, "%d",pst_DivertCallInfo->pu8_CodecsList[u8_Idx++]);
while(u8_Idx != pst_DivertCallInfo->u8_NumOfCodecs)
{
u8 u8_Len = strlen(psz_Codecs);
char psz_Temp[5]={0,};
sprintf(psz_Temp, ",%d",pst_DivertCallInfo->pu8_CodecsList[u8_Idx++]);
strcat(&psz_Codecs[u8_Len],psz_Temp);
}
}
else
{
// put codecs priority (WB, NB)
sprintf(psz_Codecs, "%d,%d", (CMBS_AUDIO_CODEC_PCM_LINEAR_WB), (CMBS_AUDIO_CODEC_PCM_LINEAR_NB));
}
st_Properties[0].e_IE = CMBS_IE_CALLERPARTY;
st_Properties[0].psz_Value = pst_DivertCallInfo->psz_CalledDigits;
st_Properties[1].e_IE = CMBS_IE_CALLEDPARTY;
st_Properties[1].psz_Value = pst_DivertCallInfo->psz_CallerID;
//st_Properties[1].psz_Value = ALL_HS_STRING;
st_Properties[2].e_IE = CMBS_IE_MEDIADESCRIPTOR;
st_Properties[2].psz_Value = psz_Codecs;
st_Properties[3].e_IE = CMBS_IE_CALLERNAME;
st_Properties[3].psz_Value = pst_DivertCallInfo->psz_CalledID,
st_Properties[4].e_IE = CMBS_IE_LINE_ID;
st_Properties[4].psz_Value = "1\0";
st_Properties[5].e_IE = CMBS_IE_MELODY;
st_Properties[5].psz_Value = "1\0";
st_Properties[6].e_IE = CMBS_IE_RECONNECT_CALL;
st_Properties[6].psz_Value = "1\0";
pst_DivertCallInfo->cmbsCallID = appcall_EstablishCall(st_Properties, 7);
if(pst_DivertCallInfo->cmbsCallID == ~0)
return ~0;
AppCallRouter_AddToAppCallMap(pst_DivertCallInfo->cmbsCallID,UleIntPbx_appID);
pst_Call = _appcall_CallObjGetById(pst_DivertCallInfo->cmbsCallID);
G_b_IntPbx_CallDivert = TRUE;
// check whether the calling device has specified the called party
if (strlen(pst_DivertCallInfo->psz_CalledDigits) == APP_PBX_CALL_PPARTICIPANT_DEVICE_LEN &&
pst_DivertCallInfo->psz_CalledDigits[APP_PBX_DEVICE_IDENTIFIER_OFFSET] == APP_PBX_DEVICE_IDENTIFIER)
{
u16 u16_DeviceId = 0;
u8 u8_UnitId = 1;
ST_HAN_VOICE_CALL_REQ_PARAMS st_CallReqParams;
apppbx_ConvertDeviceIdFromStr((const u8 *) &pst_DivertCallInfo->psz_CalledDigits[APP_PBX_CALL_PARTICIPANT_DEVICE_OFFSET], &u16_DeviceId);
if(pst_DivertCallInfo->psz_CalledDigits[APP_PBX_UNIT_IDENTIFIER_OFFSET] == APP_PBX_UNIT_IDENTIFIER)
{
apppbx_ConvertUnitIdFromStr((const u8 *) &pst_DivertCallInfo->psz_CalledDigits[APP_PBX_CALL_PARTICIPANT_UNIT_OFFSET], &u8_UnitId);
}
// st_CallReqParams.u32_FieldMask = CMBS_HAN_OTHER_PARTY_ID_MASK;
// st_CallReqParams.pu8_OtherPartyId[0] = strlen(pst_DivertCallInfo->psz_CallerID);
// memcpy(&(st_CallReqParams.pu8_OtherPartyId[1]),pst_DivertCallInfo->psz_CallerID, st_CallReqParams.pu8_OtherPartyId[0]);
APP_ULE_INX_PBX_INFO_PRINT("Calling device has specified the called party - device#%d, unit %d\n", u16_DeviceId, u8_UnitId);
// Mark call as waiting to be merged
pst_Call->b_WaitingForMerge = TRUE;
// send FUN message to device requesting it to set up a call
app_DsrHanVoiceCallReq(u16_DeviceId, u8_UnitId, &st_CallReqParams);
}
else if (strlen(pst_DivertCallInfo->psz_CalledDigits) == APP_PBX_CALL_PPARTICIPANT_HS_LEN && pst_DivertCallInfo->psz_CalledDigits[APP_PBX_HS_IDENTIFIER_OFFSET] == APP_PBX_HS_IDENTIFIER)
{
u8 u8_HsNum = pst_DivertCallInfo->psz_CalledDigits[APP_PBX_CALL_PARTICIPANT_HS_NUM_OFFSET] - '0';
APP_ULE_INX_PBX_INFO_PRINT("Calling device has specified the called party - HS %d\n", u8_HsNum);
appUleIntPbx_Call2HS(pst_Call, u8_HsNum);
}
appSmartVoice_AddToCallChannelMap(pst_Call->u32_ChannelID,pst_DivertCallInfo->cmbsCallID);
return pst_DivertCallInfo->cmbsCallID;
}
EXTAPP_RC appUleIntPbx_SendDigits(IN u32 u32_cmbsCallID, IN char* psz_Digits)
{
PST_CALL_OBJ pst_Call = _appcall_CallObjGetById(u32_cmbsCallID);
if(!pst_Call)
{
printf("\n appUleIntPbx_OnDivertCall:Error\n");
return EXTAPP_RC_FAIL;
}
if(strcmp(psz_Digits,"@") == 0)
{
AppCallRouter_DivertOutgoingCall(u32_cmbsCallID,NULL,psz_Digits);
}
else
{
printf("appUleIntPbx_SendDigits: Cannot handle digits ");
}
return EXTAPP_RC_OK;
}

View File

@@ -0,0 +1,22 @@
/*!
* \file appUleIntPbx.c.h
* \brief
* \Author DSPG
*
* @(#) %filespec: appUleIntPbx.h
*
*******************************************************************************/
#if !defined( APPULEINTPBX_H )
#define APPULEINTPBX_H
#include "appCallRouter.h"
// register callbacks
EXTAPP_RC LoadUleIntPbx();
#endif // APPULEINTPBX_H

View File

@@ -0,0 +1,541 @@
/*!
* \file appVoipService.c
* \brief handle ULE internal PBX
* \Author moria
*
*
*******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "cmbs_api.h"
#include "appcall.h"
#include "appCallRouter.h"
#include "tcx_hostlog.h"
#include "cmbs_voipline.h"
#include "appCallRouter.h"
#include "appVoipService.h"
#include "appAvsService.h"
#include "dect_common.h"
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
#define APPVOIP_MAX_NUM_CALLS 10
#define APPVOIP_NO_CALL APPVOIP_MAX_NUM_CALLS
#define APPVOIP_NO_FREE_SLOTS 0xFFFFFFFF
u32 appVoipSrv_appID = 0; /* Holds appID of the current app*/
ST_VOIP_CALL_DATA G_st_VOIP_CallData[APPVOIP_MAX_NUM_CALLS];
u32 G_u32_SlotsMask;
u32 G_u32_CallIdSlotMap[APPVOIP_MAX_NUM_CALLS];
bool G_b_UseSameSlotsForDivertedCall = FALSE;
//Forward declarations for CB functions
EXTAPP_RC appVoipService_OnCallEstablish(IN u32 cmbsCallID, IN const char* calledID, IN const char* callerHandset, IN u32 lineID, IN EXTVOIP_CODEC* codecList, IN u32 codecListLength);
EXTAPP_RC appVoipService_OnCallAnswer(IN u32 cmbsCallID, IN EXTVOIP_CODEC codec);
EXTAPP_RC appVoipService_OnCallRelease(IN u32 cmbsCallID, IN EXTVOIP_RELEASE_REASON ReleaseReason);
EXTAPP_RC appVoipService_OnCallReleaseDone(IN u32 cmbsCallID);
u32 appVoipService_OnDivertCall(ST_DIVERT_CALL_INFO *pst_DivertCallInfo);
void appVoipService_GetSlotsForCall(IN u32 u32_cmbsCallID,IN EXTVOIP_CODEC e_Codec, OUT u32 *pu32_ChannelSlots);
void appVoipService_FreeSlotsForCall(IN u32 u32_cmbsCallID,IN u32 *pu32_ChannelSlots);
void appVoipService_UpdateCallState(IN u32 u32_cmbsCallID, IN EXTVOIP_CALL_STATE e_CallState);
EXTAPP_RC appVoipService_SetAudioChannel (IN u32 u32_cmbsCallID, IN u32 mediaChannelID, IN EXTVOIP_CODEC e_Codec);
EXTAPP_RC appVoipService_SendDigits(IN u32 u32_cmbsCallID, IN char* psz_Digits);
EXTAPP_RC LoadVoipService (void)
{
ST_APP_FNC_TABLE st_AppTable;
EXTAPP_RC res;
u8 u8_Idx;
memset(&st_AppTable,0x00,sizeof(ST_APP_FNC_TABLE));
st_AppTable.fncSetupCall = appVoipService_OnCallEstablish;
st_AppTable.fncAnswerCall = appVoipService_OnCallAnswer;
st_AppTable.fncDivertOutgoingCall = appVoipService_OnDivertCall;
st_AppTable.fncUpdateCallState = appVoipService_UpdateCallState;
st_AppTable.fncDisconnectCall = appVoipService_OnCallRelease;
st_AppTable.fncDisconnectCallDone = appVoipService_OnCallReleaseDone;
st_AppTable.fncSetAudioChannel = appVoipService_SetAudioChannel;
st_AppTable.fncSendDigits = appVoipService_SendDigits;
st_AppTable.LineName[0] = 0;
for (u8_Idx = 0; u8_Idx < APPVOIP_MAX_NUM_CALLS; u8_Idx++)
{
G_st_VOIP_CallData[u8_Idx].e_Call = E_APPCMBS_CALL_CLOSE;
G_st_VOIP_CallData[u8_Idx].u32_ChannelParameter = G_u32_CallIdSlotMap[u8_Idx] = APPVOIP_NO_FREE_SLOTS;
}
res = AppCallRouter_AppInit(appVoipSrv_appID, &st_AppTable);
extvoip_RegisterSlotConfigCb(appVoipService_GetSlotsForCall, appVoipService_FreeSlotsForCall);
return res;
}
u8 appVoipService_AssignNewCallId(void)
{
u8 u8_Idx;
for (u8_Idx = 0; u8_Idx < APPVOIP_MAX_NUM_CALLS; u8_Idx++)
{
if(G_st_VOIP_CallData[u8_Idx].e_Call == E_APPCMBS_CALL_CLOSE)
break;
}
return u8_Idx;
}
u8 appVoipService_GetCallId(IN u32 cmbsCallID)
{
u8 u8_Idx;
for (u8_Idx = 0; u8_Idx < APPVOIP_MAX_NUM_CALLS; u8_Idx++)
{
if(G_st_VOIP_CallData[u8_Idx].u32_CmbsCallId == cmbsCallID && G_st_VOIP_CallData[u8_Idx].e_Call != E_APPCMBS_CALL_CLOSE)
break;
}
return u8_Idx;
}
void appVoipService_UpdateCallState(IN u32 u32_cmbsCallID, IN EXTVOIP_CALL_STATE e_CallState)
{
u8 u8_CallId = appVoipService_GetCallId(u32_cmbsCallID);
if (u8_CallId == APPVOIP_NO_CALL)
{
printf("\n appVoipService_UpdateCallState: Invalid call id \n");
}
else
{
G_st_VOIP_CallData[u8_CallId].e_Call = e_CallState;
printf("\n appVoipService_UpdateCallState: %d\n", e_CallState);
}
return;
}
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
EXTAPP_RC appVoipService_OnCallAnswer(IN u32 u32_cmbsCallID, IN EXTVOIP_CODEC codec)
{
u32 u32_ChannelSlots;
u8 u8_CallId = appVoipService_GetCallId(u32_cmbsCallID);
if(u8_CallId == APPVOIP_NO_CALL)
{
printf("\nappVoipService_OnCallAnswer: Invalid call Id\n");
return EXTVOIP_RC_FAIL;
}
if (G_b_UseSameSlotsForDivertedCall)
{
u32_ChannelSlots = G_st_VOIP_CallData[u8_CallId].u32_ChannelParameter;
}
else
{
appVoipService_GetSlotsForCall(u32_cmbsCallID,codec,&u32_ChannelSlots);
G_st_VOIP_CallData[u8_CallId].u32_ChannelParameter = u32_ChannelSlots;
}
if(u32_ChannelSlots != APPVOIP_NO_FREE_SLOTS)
{
if(appmedia_CallObjMediaStart(0,u32_cmbsCallID,u32_ChannelSlots,NULL))
G_st_VOIP_CallData[u8_CallId].e_Media = E_APPCMBS_MEDIA_ACTIVE;
}
else
{
printf("\n appVoipService_OnCallAnswer: No free slots for call %d \n", u8_CallId);
}
return EXTAPP_RC_OK;
}
u32 appVoipService_OnDivertCall(ST_DIVERT_CALL_INFO *pst_DivertCallInfo)
{
u32 u32_ActiveCmbsCallId;
ST_EXTVOIPCALLINFO st_CallInfo = {0,};
PST_CALL_OBJ pst_Call;
EXTVOIP_CODEC p_CodecList[] = {EXTVOIP_CODEC_PCM_LINEAR_WB, EXTVOIP_CODEC_PCM_LINEAR_NB};
if(!pst_DivertCallInfo)
{
printf("\n appVoipService_OnDivertCall: Error \n");
return EXTAPP_RC_FAIL;
}
u32_ActiveCmbsCallId = pst_DivertCallInfo->cmbsCallID;
// get call object
pst_Call = _appcall_CallObjGetById(u32_ActiveCmbsCallId);
if ( !pst_Call )
{
printf("appVoipService_OnDivertCall : NO SUCH CALL WITH ID %d\n", u32_ActiveCmbsCallId);
return EXTAPP_RC_FAIL;
}
if(pst_DivertCallInfo->u8_NumOfCodecs)
{
st_CallInfo.p_codecList = pst_DivertCallInfo->pu8_CodecsList;
st_CallInfo.codecListLen = pst_DivertCallInfo->u8_NumOfCodecs;
}
else
{
st_CallInfo.codecListLen = 2;
st_CallInfo.p_codecList = p_CodecList;
}
st_CallInfo.psz_CallerParty = pst_DivertCallInfo->psz_CalledDigits;
st_CallInfo.psz_CalledParty = pst_DivertCallInfo->psz_CallerID;
st_CallInfo.psz_CallerName = pst_DivertCallInfo->psz_CalledID;
st_CallInfo.LineId = 1;
st_CallInfo.Melody = 1;
pst_DivertCallInfo->cmbsCallID = extvoip_MakeIncomingCall(appVoipSrv_appID,&st_CallInfo,1);
if(_appcall_CallObjGetById(pst_DivertCallInfo->cmbsCallID))
{
u8 u8_CallId = appVoipService_AssignNewCallId();
if(u8_CallId != APPVOIP_NO_CALL)
{
G_st_VOIP_CallData[u8_CallId].u32_CmbsCallId = pst_DivertCallInfo->cmbsCallID;
G_st_VOIP_CallData[u8_CallId].u32_ChannelParameter = pst_DivertCallInfo->u32_ChannelParameter;
G_st_VOIP_CallData[u8_CallId].e_Media = E_APPCMBS_MEDIA_PEND;
G_st_VOIP_CallData[u8_CallId].e_Call= E_APPCMBS_CALL_OUT_PROC;
return EXTAPP_RC_OK;
}
else
{
printf("\nappVoipService_OnDivertCall: unable to assign new voip callId\n");
return EXTAPP_RC_FAIL;
}
}
else
{
printf("\nappVoipService_OnDivertCall: unable to divert call\n");
return EXTAPP_RC_FAIL;
}
appSmartVoice_AddToCallChannelMap(pst_DivertCallInfo->u32_ChannelID,u32_ActiveCmbsCallId);
return pst_DivertCallInfo->cmbsCallID;
}
EXTAPP_RC appVoipService_OnCallEstablish(IN u32 cmbsCallID, IN const char* calledID, IN const char* callerHandset, IN u32 lineID, IN EXTVOIP_CODEC* codecList, IN u32 codecListLength)
{
PST_VOIP_CALL_DATA pst_CallData;
ST_APPCALL_PROPERTIES st_Properties;
u8 u8_CallId = appVoipService_AssignNewCallId();
if (u8_CallId == APPVOIP_NO_CALL)
{
printf("\n appVoipService_OnCallEstablish: Error \n");
return EXTAPP_RC_FAIL;
}
pst_CallData = &G_st_VOIP_CallData[u8_CallId];
pst_CallData->u32_CmbsCallId = cmbsCallID;
printf("\n<<<<<< appVoipService_OnCallEstablish >>>>>>>\n");
if(!codecListLength)
pst_CallData->e_Codec = EXTVOIP_CODEC_PCM_LINEAR_WB;
else
pst_CallData->e_Codec = codecList[0];
appVoipService_GetSlotsForCall(cmbsCallID, pst_CallData->e_Codec, &(pst_CallData->u32_ChannelParameter));
pst_CallData->e_Media = E_APPCMBS_MEDIA_PEND;
st_Properties.e_IE = CMBS_IE_CALLPROGRESS;
st_Properties.psz_Value = "CMBS_CALL_PROGR_SETUP_ACK\0";
appcall_ProgressCall(&st_Properties, 1, (u16)cmbsCallID, NULL);
if(lineID == APPCALL_NO_LINE) //no line id
{
static char s_reason[5] = { 0 };
sprintf(s_reason, "%d", CMBS_REL_REASON_USER_BUSY);
// disconnecting call
st_Properties.e_IE = CMBS_IE_CALLRELEASE_REASON;
st_Properties.psz_Value = s_reason;
appcall_ReleaseCall(&st_Properties, 1, (u16)cmbsCallID, NULL);
return EXTAPP_RC_FAIL;
}
st_Properties.e_IE = CMBS_IE_CALLPROGRESS;
st_Properties.psz_Value = "CMBS_CALL_PROGR_PROCEEDING\0";
appcall_ProgressCall(&st_Properties, 1, (u16)cmbsCallID, NULL);
pst_CallData->e_Call = E_APPCMBS_CALL_OUT_PROC;
return EXTAPP_RC_OK;
}
EXTAPP_RC appVoipService_OnCallRelease(IN u32 cmbsCallID, IN EXTVOIP_RELEASE_REASON ReleaseReason)
{
printf("\nappVoipService_OnCallRelease\n");
return EXTAPP_RC_OK;
}
EXTAPP_RC appVoipService_OnCallReleaseDone(IN u32 cmbsCallID)
{
printf("\appVoipService_OnCallReleaseDone\n");
u8 u8_CallId = appVoipService_GetCallId(cmbsCallID);
if (u8_CallId == APPVOIP_NO_CALL)
{
printf("\n appVoipService_OnCallReleaseDone: Call already released \n");
return EXTAPP_RC_FAIL;
}
appVoipService_FreeSlotsForCall(cmbsCallID,&(G_st_VOIP_CallData[u8_CallId].u32_ChannelParameter));
G_st_VOIP_CallData[u8_CallId].e_Call = E_APPCMBS_CALL_CLOSE;
G_st_VOIP_CallData[u8_CallId].e_Media = E_APPCMBS_MEDIA_CLOSE;
return EXTAPP_RC_OK;
}
void appVoipService_OnMediaChange(u32 u32_CallID, EXTVOIP_CODEC e_Codec)
{
u8 u8_CallId = appVoipService_GetCallId(u32_CallID);
if (u8_CallId == APPVOIP_NO_CALL)
{
printf("\n appVoipService_OnMediaChange: Invalid call ID \n");
return;
}
// answer current call
extvoip_OnAnswerCall(u32_CallID, e_Codec);
if( G_st_VOIP_CallData[u8_CallId].u32_ChannelParameter != 0xFF)
{
G_u32_CallIdSlotMap[u32_CallID] = G_st_VOIP_CallData[u8_CallId].u32_ChannelParameter;
appmedia_CallObjMediaStart(0,u32_CallID,G_st_VOIP_CallData[u8_CallId].u32_ChannelParameter,NULL);
printf("\nappVoipService_OnMediaChange: Success\n");
}
else
printf("\n nappVoipService_OnMediaChange: ERROR \n ");
return;
}
void appVoipService_GetSlotsForCall(IN u32 u32_cmbsCallID,IN EXTVOIP_CODEC e_Codec, OUT u32 *pu32_ChannelSlots)
{
u32 u32_Slots;
u8 u8_SlotMaxOffset = 0, u8_Idx;
switch (e_Codec)
{
case EXTVOIP_CODEC_PCMU:
case EXTVOIP_CODEC_PCMA:
case EXTVOIP_CODEC_PCM8:
u32_Slots = 0x01;
u8_SlotMaxOffset = 31;
break;
case EXTVOIP_CODEC_PCMU_WB:
case EXTVOIP_CODEC_PCMA_WB:
case EXTVOIP_CODEC_PCM_LINEAR_NB:
u32_Slots = 0x03;
u8_SlotMaxOffset = 30;
break;
case EXTVOIP_CODEC_PCM_LINEAR_WB:
u32_Slots = 0x0F;
u8_SlotMaxOffset = 28;
break;
default:
DECT_DBG("appVoipService_GetSlotsForCall - Unsupported codec!\n");
*pu32_ChannelSlots = APPVOIP_NO_FREE_SLOTS;
DECT_DBG("\n\nNo free slots - aborting media start\n\n");
}
if (u8_SlotMaxOffset > 0)
{
for (u8_Idx = 0; u8_Idx <= u8_SlotMaxOffset; ++u8_Idx)
{
if ( ((u32_Slots << u8_Idx) & G_u32_SlotsMask) == 0 )
{
break;
}
}
if ( u8_Idx <= u8_SlotMaxOffset )
{
/* available slots exist */
//st_MediaChannel.u32_ChannelParameter = u32_Slots << u8_Idx;
*pu32_ChannelSlots = u32_Slots << u8_Idx;
G_u32_SlotsMask |= *pu32_ChannelSlots;
}
}
G_u32_CallIdSlotMap[u32_cmbsCallID] = *pu32_ChannelSlots;
}
void appVoipService_FreeSlotsForCall(IN u32 u32_cmbsCallID,IN u32 *pu32_ChannelSlots)
{
G_u32_CallIdSlotMap[u32_cmbsCallID] = APPVOIP_NO_FREE_SLOTS;
G_u32_SlotsMask &= (u32)(~(*pu32_ChannelSlots));
return;
}
EXTAPP_RC appVoipService_SetAudioChannel (IN u32 cmbsCallID, IN u32 mediaChannelID, IN EXTVOIP_CODEC e_Codec)
{
u8 u8_CallId = appVoipService_GetCallId(cmbsCallID);
if (u8_CallId == APPVOIP_NO_CALL)
{
printf("\n appVoipService_SetAudioChannel: Error \n");
return EXTAPP_RC_FAIL;
}
G_st_VOIP_CallData[u8_CallId].u32_ChannelID = mediaChannelID;
G_st_VOIP_CallData[u8_CallId].e_Codec = e_Codec;
#if 0
// answer current call
extvoip_OnAnswerCall(cmbsCallID, e_Codec);
#endif
if (extvoip_CallMediaStart(cmbsCallID, G_st_VOIP_CallData[u8_CallId].u32_ChannelParameter))
{
G_st_VOIP_CallData[u8_CallId].e_Media = E_APPCMBS_MEDIA_ACTIVE;
return EXTAPP_RC_OK;
}
else
{
printf("\n appVoipService_SetAudioChannel: ERROR \n ");
return EXTAPP_RC_FAIL;
}
}
EXTAPP_RC appVoipService_SendDigits(IN u32 u32_cmbsCallID, IN char* psz_Digits)
{
u8 u8_CallId = appVoipService_GetCallId(u32_cmbsCallID);
if (u8_CallId == APPVOIP_NO_CALL)
{
printf("\n appVoipService_SendDigits: Invalid call Id \n");
return EXTAPP_RC_FAIL;
}
if(strcmp(psz_Digits,"@") == 0)
{
AppCallRouter_DivertOutgoingCall(u32_cmbsCallID,NULL,psz_Digits);
}
else
{
ST_APPCALL_PROPERTIES st_Properties;
printf("send digits to network");
st_Properties.e_IE = CMBS_IE_CALLPROGRESS;
st_Properties.psz_Value = "CMBS_CALL_PROGR_RINGING\0";
appcall_ProgressCall(&st_Properties, 1, (u16)u32_cmbsCallID, NULL);
}
return EXTAPP_RC_OK;
}
void appVoipService_EstablishIncomingCall(void)
{
u32 u32_cmbsCallID;
EXTVOIP_CODEC codecList[2] = { EXTVOIP_CODEC_PCM_LINEAR_WB,EXTVOIP_CODEC_PCM_LINEAR_NB };
char psz_CallerName[] = "Inc Test Call";
char psz_CallerParty[] = "124571";
char psz_CalledParty[] = "h123456789A";
ST_EXTVOIPCALLINFO st_CallInfo = {psz_CallerName,psz_CallerParty,psz_CalledParty,0,codecList,2};
u32_cmbsCallID = extvoip_MakeIncomingCall(appVoipSrv_appID,&st_CallInfo,0);
if(_appcall_CallObjGetById(u32_cmbsCallID))
{
u8 u8_CallId = appVoipService_AssignNewCallId();
if(u8_CallId != APPVOIP_NO_CALL)
{
G_st_VOIP_CallData[u8_CallId].u32_CmbsCallId = u32_cmbsCallID;
G_st_VOIP_CallData[u8_CallId].e_Call = E_APPCMBS_CALL_INC_PEND;
G_st_VOIP_CallData[u8_CallId].e_Media = E_APPCMBS_MEDIA_PEND;
return;
}
else
{
printf("\appVoipService_EstablishIncomingCall: unable to assign new voip callId\n");
return;
}
}
}
void appVoipService_AnswerCall(u32 u32_cmbsCallID)
{
u8 u8_CallId = appVoipService_GetCallId(u32_cmbsCallID);
if (u8_CallId == APPVOIP_NO_CALL)
{
printf("\n appVoipService_AnswerCall: Error \n");
return ;
}
extvoip_OnAnswerCall(u32_cmbsCallID, G_st_VOIP_CallData[u8_CallId].e_Codec);
}
void appVoipService_ReleaseCall(u32 u32_cmbsCallID)
{
u8 u8_CallId = appVoipService_GetCallId(u32_cmbsCallID);
if (u8_CallId == APPVOIP_NO_CALL)
{
printf("\n appVoipService_AnswerCall: Error \n");
return;
}
extvoip_OnDisconnectCall(u32_cmbsCallID,EXTVOIP_REASON_NORMAL);
}

View File

@@ -0,0 +1,27 @@
/*!
* \file appVoipService.h
* \brief
* \Author DSPG
*
* @(#) %filespec: appVoipService.h
*
*******************************************************************************/
typedef struct
{
u32 u32_CmbsCallId; /*!< Call Instance to identify the call on CMBS */
u32 u32_ChannelID; /*!< Channel ID to identify the media connection on CMBS */
u32 u32_ChannelParameter; /*!< Channel Parameter provides information about the parameter settings, e.g. IOM - used slots */
EXTVOIP_CODEC e_Codec; /*!< used codec */
u8 pu8_CodecsList[EXTVOIP_CODEC_MAX]; /*!< Codecs list */
u8 u8_CodecsLength; /*!< Codecs list length */
E_APPCMBS_CALL e_Call; /*!< call state */
E_APPCMBS_MEDIA e_Media; /*!< media entity state */
bool b_Incoming; /*!< TRUE for incoming calls, FALSE o/w */
} ST_VOIP_CALL_DATA, * PST_VOIP_CALL_DATA;
// register callbacks
EXTAPP_RC LoadVoipService(void);
void appVoipService_EstablishIncomingCall(void);
void appVoipService_AnswerCall(u32 u32_cmbsCallID);
void appVoipService_ReleaseCall(u32 u32_cmbsCallID);

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,302 @@
/*!
* \file appcall.h
* \brief
* \Author DSPG
*
* @(#) %filespec: appcall.h~NBGD53#18 %
*
*******************************************************************************
* \par History
* \n==== History ============================================================
* date name version action
* ----------------------------------------------------------------------------
*
* 12-Jun-2013 tcmc_asa brought verison 18 (2.99.9) to 3.x branch
* 28-Jan-2013 tcmc_asa 18 Added appcall_CallInbandInfoCNIP(), PR 3615
* 24-Jan-2013 tcmc_asa 17 Added E_APPCALL_SWITCH_RECEIVED_CODEC
*
*******************************************************************************/
#if !defined( APPCALL_H )
#define APPCALL_H
#include "cmbs_api.h"
#include "cfr_ie.h"
#ifdef PNCAP
#include "pncap_def.h"
#endif
typedef enum
{
E_APPCALL_AUTOMAT_MODE_OFF, /*!< call object automat mode off */
E_APPCALL_AUTOMAT_MODE_ON /*!< call object automat mode on, incoming and outgoing calls shall be handled in simple statemachine */
}E_APPCALL_AUTOMAT_MODE;
typedef enum
{
E_APPCALL_PREFERRED_CODEC_RECEIVED_CODEC,
E_APPCALL_PREFERRED_CODEC_WB, /*! G722 */
E_APPCALL_PREFERRED_CODEC_NB, /*! G726 */
E_APPCALL_SWITCH_RECEIVED_CODEC /* WB->NB or NB->WB */
}E_APPCALL_PREFERRED_CODEC;
/*! \brief exchange structure between CMBS API layer and upper application */
typedef struct
{
E_CMBS_IE_TYPE e_IE; /*! IE type */
char * psz_Value; /*! string value in case of upper -> CMBS API layer */
}ST_APPCALL_PROPERTIES, * PST_APPCALL_PROPERTIES;
/*! \brief CMBS API layer call states */
typedef enum
{
E_APPCMBS_CALL_CLOSE, /*!< line is closed */
E_APPCMBS_CALL_INC_PEND, /*!< CMBS target is informed of an incoming call*/
E_APPCMBS_CALL_INC_RING, /*!< CMBS target let the handset ringing */
E_APPCMBS_CALL_OUT_PEND, /*!< CMBS-API layer received a outgoing call establishment event */
E_APPCMBS_CALL_OUT_PEND_DIAL, /*!< Digits will be collected in CLD array, if Dialtone was switched on.
it is automatically switched off, if call enters this state */
E_APPCMBS_CALL_OUT_INBAND, /*!< The outgoing call is set-up to carry inband signalling, e.g. network tones */
E_APPCMBS_CALL_OUT_PROC, /*!< The outgoing call is proceeding state */
E_APPCMBS_CALL_OUT_RING, /*!< The outgoing call is in ringing state, if not the inband tone is available */
E_APPCMBS_CALL_ACTIVE, /*!< The call is in active mode, media shall be transmitted after channel start */
E_APPCMBS_CALL_RELEASE, /*!< The call is in release mode */
E_APPCMBS_CALL_ON_HOLD, /*!< The call is on hold */
E_APPCMBS_CALL_CONFERENCE, /*!< The call is in conference mode */
E_APPCMBS_CALL_SCREENING, /*!< The call is in screening mode */
}E_APPCMBS_CALL;
/*! \brief CBS API layer media state */
typedef enum
{
E_APPCMBS_MEDIA_CLOSE, /*!< Media entity is closed */
E_APPCMBS_MEDIA_PEND, /*!< Media entity is prepared, codec negotiated and channel ID from Target available */
E_APPCMBS_MEDIA_ACTIVE /*!< Media entity is started to stream */
} E_APPCMBS_MEDIA;
/*! \brief Line node, it contains every important information of the line */
typedef struct
{
u32 u32_foo; /*!< foo */ //TODO
} ST_LINE_OBJ, * PST_LINE_OBJ;
#define APPCALL_INVALID_HS_NUM 0xFF
#define MAX_NUM_OF_PARTICIPANTS_IN_CONFERENCE 10
#define CALL_PARTICIPANT_ID_MAX_LEN 30
/*! \brief Call node, it contains every important information of the connection */
typedef struct
{
u32 u32_CallInstance; /*!< Call Instance to identify the call on CMBS */
u8 u8_LineId; /*!< Line ID*/
u8 u8_LineSubType; /*!< Line Sub Type*/
ST_IE_CALLERPARTY st_CallerParty; /*!< Caller Party, incoming call CLI, outgoing call Handset number */
ST_IE_CALLEDPARTY st_CalledParty; /*!< Called Party, incoming call ringing mask, outgoing call to be dialed number */
ST_IE_CALLERPARTY st_TmpParty; /*!< further feature, temp party, e.g. call waiting active and the CMBS API layer has to restore connection*/
char ch_TmpParty[CALL_PARTICIPANT_ID_MAX_LEN]; /*!< buffer of temp party number */
char ch_CallerID[CALL_PARTICIPANT_ID_MAX_LEN]; /*!< buffer of caller party number */
char ch_CalledID[CALL_PARTICIPANT_ID_MAX_LEN]; /*!< buffer of called party number */
u32 u32_ChannelID; /*!< Channel ID to identify the media connection on CMBS */
u32 u32_ChannelParameter; /*!< Channel Parameter provides information about the parameter settings, e.g. IOM - used slots */
E_CMBS_AUDIO_CODEC e_Codec; /*!< used codec */
u8 pu8_CodecsList[CMBS_AUDIO_CODEC_MAX]; /*!< Codecs list */
u8 u8_CodecsLength; /*!< Codecs list length */
E_APPCMBS_CALL e_Call; /*!< call state */
E_APPCMBS_MEDIA e_Media; /*!< media entity state */
bool b_Incoming; /*!< TRUE for incoming calls, FALSE o/w */
bool b_CodecsOfferedToTarget; /*!< TRUE when codecs have been sent to target (relevant for outgoing calls only) */
bool b_IsSplashRing; /*!< TRUE when this call is for Splash Ring only */
bool b_WaitingForMerge; /*!< TRUE if call is waiting to be merged, FALSE o/w */
u8 pu8_ListOfParticipants[MAX_NUM_OF_PARTICIPANTS_IN_CONFERENCE][CALL_PARTICIPANT_ID_MAX_LEN]; /*!< stores participant ids for all participants of the call */
u8 u8_NumOfParticipants; /*!< stores number of participants in the call */
} ST_CALL_OBJ, * PST_CALL_OBJ;
typedef struct
{
u8 u8_CallReleaseInProgress;
u32 u32_CallInstance;
ST_IE_RELEASE_REASON st_Reason;
bool b_SendReleaseRequest;
}ST_CALL_RELEASE;
typedef struct
{
u32 u32_CallInstance_1;
u32 u32_CallInstance_2;
}ST_CMBS_APP_CONF_CALL_ENTRY, *PST_CMBS_APP_CONF_CALL_ENTRY;
#ifdef PNCAP
typedef enum {
DateTimeSync,
MWISend,
MissedCallNotification,
NameNumber
}ePnCapAttribute;
typedef struct {
u8 IntName[26];
int u8_IntNum;
int u8_Coding;
}pncap_name_and_number;
typedef union {
/** all values should be in BCD format */
struct pncap_date_and_time PnCapDateTime;
pncap_name_and_number PnCapNameNum;
u8 u8_MessagesWaiting;
}UnionPnCapFacility;
typedef enum{
PNCAP_RESERVE_FACILITY=1
}ePnCapReserved;
#endif
#define CMBS_MAX_NUMBER_OF_CONFERENCE_CALLS 5
/*! \brief max line */
#define APPCALL_LINEOBJ_MAX 40
/*! \brief max connection for CMBS API layer */
#if (NBS==1)
#define APPCALL_CALLOBJ_MAX 10
#else
#define APPCALL_CALLOBJ_MAX 8
#endif
#define APPCALL_NO_LINE 0xFF
#define APPCALL_NO_CALL 0xFFFF
#define APPCALL_NO_INDEX 0xFF
#define APPCALL_NO_MEDIA_CHANNEL 0xFF
#define ALL_HS_STRING "h123456789A\0"
#define ALL_HS_1 "h1\0"
#define ALL_HS_2 "h2\0"
#define ALL_HS_3 "h3\0"
#define ALL_HS_4 "h4\0"
#define ALL_HS_5 "h5\0"
#define ALL_HS_6 "h6\0"
#define ALL_HS_7 "h7\0"
#define ALL_HS_8 "h8\0"
#define ALL_HS_9 "h9\0"
#define ALL_HS_10 "hA\0"
#define CALL_RELEASE_0 "0\0"
#define CALL_RELEASE_1 "1\0"
#define CALL_RELEASE_2 "2\0"
#define CALL_RELEASE_3 "3\0"
#define CALL_RELEASE_4 "4\0"
#define CMBS_MULTICALL_LINE_NUM_OF_CALLS 2
#define CMBS_NO_LINE_DEFINED 0x7F
#define CMBS_NO_ENTRY_FOUND 0xFF
#define CMBS_MAX_NUM_OF_LINES 5
typedef struct
{
u16 u16_CallId;
ST_CALL_OBJ st_CallInfo;
} ST_SINGLE_CALL_INFO, * PST_SINGLE_CALL_INFO;
typedef struct
{
u16 u16_NumberOfActiveCalls;
ST_SINGLE_CALL_INFO st_ActiveCallInfo[APPCALL_CALLOBJ_MAX];
}ST_ALLACTIVECALLSINFO, * PST_ALLACTIVECALLSINFO;
#if defined( __cplusplus )
extern "C"
{
#endif
void appcall_Initialize (void);
void appcall_AutomatMode ( E_APPCALL_AUTOMAT_MODE e_Mode );
u16 appcall_EstablishCall ( PST_APPCALL_PROPERTIES pst_Properties, int n_Properties );
void appcall_ReconnectSwitch(u16 u16_SrCallId, u16 u16_DestCallId, PST_APPCALL_PROPERTIES pst_Properties);
int appcall_ReleaseCall( PST_APPCALL_PROPERTIES pst_Properties, int n_Properties, u16 u16_CallId, char * psz_CLI );
int appcall_AnswerCall ( PST_APPCALL_PROPERTIES pst_Properties, int n_Properties, u16 u16_CallId, char * psz_CLI );
int appcall_ProgressCall ( PST_APPCALL_PROPERTIES pst_Properties, int n_Properties, u16 u16_CallId, char * psz_CLI );
int appcall_DisplayCall ( PST_APPCALL_PROPERTIES pst_Properties, int n_Properties, u16 u16_CallId, char * psz_CLI );
int appcall_DisplayString ( PST_APPCALL_PROPERTIES pst_Properties, int n_Properties, u16 u16_CallId, char * psz_Display );
int appcall_ResumeCall( u16 u16_CallId, char * psz_CLI );
int appcall_HoldCall( u16 u16_CallId, char * psz_CLI );
int appcall_CallInbandInfo( u16 u16_CallId, char * psz_CLI );
int appcall_CallInbandInfoCNIP( u16 u16_CallId, char * pu8_Name, char * pu8_FirstName, char * pch_cli );
int appcall_MergeCalls( u16 u16_CallId1, u16 u16_CallId2, u8 u8_CovertToInt );
int appcall_AnswerFxsCall(u16 u16_CallId1);
int appcall_MakeSPKOgCall(u16 u8_HsNo);
int appcall_EmergencyCallRelease( u16 u16_CallId );
int appcall_EmergencyCallReleaseByCallInstance( u16 u16_CallInstance );
u16 appcall_EstablishSplashRing( PST_APPCALL_PROPERTIES pst_Properties, int n_Properties, u8 u8_SplashTimer );
void appcall_ReleaseSplashRingCall(PST_CALL_OBJ pst_Call);
/* appmedia_CallObjTonePlay: u16_ToneDur parameter & u16_DTMFToneToHSMask are only valid for DTMF request.
* For all other tones values should be 0 (will be ignored)
*/
void appmedia_CallObjTonePlay(char *psz_Value, u16 u16_ToneVolume, int bo_On, u16 u16_CallId, char *psz_CLI, u16 u16_ToneDur, u16 u16_DTMFToneToHSMask);
bool appmedia_CallObjMediaStart( u32 u32_CallInstance, u16 u16_CallId, u32 u32_ChannelSlots, char * psz_CLI );
void appmedia_CallObjMediaStop( u32 u32_CallInstance, u16 u16_CallId, char * psz_CLI );
void appmedia_CallObjMediaOffer( u16 u16_CallId, char ch_Audio );
void appcall_InfoPrint ( void );
bool appcall_IsHsInCallWithLine ( u8 u8_HsNumber, u8 u8_LineId );
bool appcall_IsLineInUse ( u8 u8_LineId );
void appcall_HandleLineUseStatus (u8 u8_LineId);
void appcall_HandleHSUseStatus (u8 u8_LineId, u16 u16_HsNr, bool b_InUse);
u8 appcall_GetMaximumNumberOfAllowedCalls(u8 u8_LineId);
void appcall_SetActiveCallTable(u8 u8_Line, u32 u32_CallInstanse);
void appcall_RemoveCallFromTable(u8 u8_Line, u32 u32_CallInstanse);
bool appcall_IsCallInTable(u8 u8_Line, u32 u32_CallInstanse);
u8 appcall_GetNumOfActiveCallsForLine(u8 u8_Line);
bool appcall_CheckHSInOtherCall(u8 u8_Line, u16 u16_HSNum, u32 u32_CallInstance);
u16 appcall_GetHSMask(u8 u8_Line, u32 u32_CallInstanse);
void appcall_SetHSMask(u8 u8_Line, u32 u32_CallInstanse, u16 u16_HSMask);
void appcall_HSUseChange(u8 u8_LineId, u16 u16_HSMask, u32 u32_CallInstance);
void appcall_SetHsStatus( u32 u32_CallInstanse, PST_IE_CALL_STATE st_CallState);
void appcall_GetHsStatus( u8 u8_HsNo, ST_IE_CALL_STATE *st_CallState);
void appcall_ConferenceCallTableClearEntry(u32 u32_CallInstance);
u32 appcall_ConferencePartnerGet(u32 u32_CallInstance);
u8 appcall_ConferenceCallTableSet(u32 u32_CallInstance_to, u32 u32_CallInstance_frm);
void appcall_ConferenceCallTableInit();
void appcall_RefreshCallInfo();
void appcall_HsStatusInit(void);
void appcall_GetActiveCallsInfo(void);
#ifdef PNCAP
u16 appcall_PnCapDataCallStart( u16 u16_HsNo );
u16 appcall_PnCapDataPacketSend( u8 *u8_Name, u8 *u8_Num, u16 u16_CallId );
u16 appcall_PnCapDataTransferStop( u16 u16_CallId );
u16 appcall_PnCapDataCallProc(u16 u16_CallId , u16 u16_HsNo);
u16 appcall_PnCapDataCallCfm(u16 u16_CallId , u16 u16_HsNo);
u16 appcall_PnCapPhoneBookActivate(u16 u16_HsNo );
void appcall_PnCapAttribute(ePnCapAttribute PncapAttribute, UnionPnCapFacility AttributeStructure, u16 u16_HSMask );
#endif
ST_CALL_OBJ *appcall_GetCallPendingforDeviceObj(PST_CALL_OBJ pst_Call);
void app_Call2HS(PST_CALL_OBJ pst_Call, u16 u16_DstId);
//void app_PrintCallInfo( E_CMBS_CALL_INFO e_Info );
PST_CALL_OBJ _appcall_CallObjGetById( u16 u16_CallId );
u16 _appcall_CallObjIdGet(PST_CALL_OBJ pst_Call);
PST_CALL_OBJ _appcall_CallObjGet(u32 u32_CallInstance, char *psz_CLI);
u32 appcall_AllocateSlots(u32 u32_NumSlots);
void appcall_DeallocateSlots(u32 u32_Slots);
#if defined( __cplusplus )
}
#endif
#endif // APPCALL_H
//*/

View File

@@ -0,0 +1,622 @@
/*!
\brief Initialize the CMBS application
*/
#include <stdio.h>
#include <unistd.h>
#include <termios.h>
#include <string.h>
#include <sys/time.h> //we need <sys/select.h>; should be included in <sys/types.h> ???
#include <signal.h>
#include <sys/msg.h>
#include <errno.h>
#include "cmbs_platf.h"
#include "cmbs_api.h"
#include "cmbs_han.h"
#include "cmbs_util.h"
#include "cmbs_dbg.h"
#include "cfr_ie.h"
#include "cfr_mssg.h"
#include "appcmbs.h"
#include "appsrv.h"
#include "appcall.h"
#include "applog.h"
#include "apphan.h"
#include "appfacility.h"
#include "appmsgparser.h"
#ifdef Q_AUTO
#include <jsystem_tx.h>
#endif
#include "appHanMw.h"
#include "ListsApp.h"
#ifdef CMBS_PLUGIN
#include "cmbs_plugin.h"
#endif
extern u8 u8_APP_LA_Initialized;
extern void app_LaInitialize(void);
extern u8 tcx_DetectComPort(bool interactiveMode, E_CMBS_DEVTYPE *pu8_type);
extern void tcx_USBConfig(u8 u8_Port, u32 u32_BaudRate);
u32 g_u32_BaudRate = 115200;
extern ST_CMBS_DEV g_st_DevMedia;
extern ST_CMBS_DEV g_st_DevCtl;
ST_CB_LOG_BUFFER pfn_log_buffer_Cb;
#define DEFAULT_MAX_TRANSFER_SIZE (240)
u32 g_CMBSMaxTransferSize = DEFAULT_MAX_TRANSFER_SIZE;
ST_CMBS_APP_INST g_CMBSAppInstance;
extern void cmbs_api_MsgQDestroy(int nMsgQId);
extern int cmbs_api_MsgQCreate(void);
//Target alive indication callback
static t_fptrHANTargetAliveIndication g_fptrHANTargetAliveIndication = NULL;
/*!***************************************************************************
*
* \brief CMBS application feedback entity
*
*****************************************************************************/
// different CMBS parts use different entities
// which will be called by callback function
// if the entity consumes the event, it shall return TRUE
typedef int (*PFN_APP_ENTITY_CB)(void *pv_AppRef,
E_CMBS_EVENT_ID e_EventID,
void *pv_EventIEListRef);
// a flag for external Client
t_e_ExternalClient g_e_externalClient = NO_EXTERNAL_CLIENT;
t_e_ExternalClient appcmbs_GetExternalClientInformation()
{
return g_e_externalClient;
}
void appcmbs_RegisterTargetAliveIndicationCB(t_fptrHANTargetAliveIndication fpt_registerCallBackForTargetAliveIndication)
{
g_fptrHANTargetAliveIndication = fpt_registerCallBackForTargetAliveIndication;
}
void appcmbs_SetExternalClientInformation(t_e_ExternalClient client)
{
g_e_externalClient = client;
}
// global callback function table of received CMBS Events
PFN_APP_ENTITY_CB g_pfn_app_Entity[] =
{
(PFN_APP_ENTITY_CB)app_ServiceEntity,
(PFN_APP_ENTITY_CB)app_CallEntity,
(PFN_APP_ENTITY_CB)app_SwupEntity,
NULL, //(PFN_APP_ENTITY_CB)app_MediaEntity - currently inside call entity
(PFN_APP_ENTITY_CB)app_FacilityEntity,
#ifdef CMBS_PLUGIN
(PFN_APP_ENTITY_CB)app_PluginEntity,
#endif
(PFN_APP_ENTITY_CB)app_DataEntity,
(PFN_APP_ENTITY_CB)app_LaEntity,
(PFN_APP_ENTITY_CB)app_UleDataEntity,
// suotafile will be first so if it is enabled and consume the event, the suota app will not interfere
(PFN_APP_ENTITY_CB)app_SuotaFileEntity,
(PFN_APP_ENTITY_CB)app_SuotaEntity,
(PFN_APP_ENTITY_CB)app_HANEntity,
(PFN_APP_ENTITY_CB)app_RTPEntity,
(PFN_APP_ENTITY_CB)app_LogEntity,
(PFN_APP_ENTITY_CB)app_CmdEntity
#if defined (CRASH_DUMP)
,
(PFN_APP_ENTITY_CB)app_CrashDumpEntity
#endif
};
// global object of application
ST_CMBS_APPL g_cmbsappl;
u8 g_HoldCfm = 1; /* 0 - decline hold, 1 - accept hold */
u8 g_HoldResumeCfm = 1; /* 0 - decline hold resume, 1 - accept hold resume */
u8 g_TransferAutoCfm = 1;
u8 g_ConfAutoCfm = 1;
u8 g_EarlyMediaAutoCfm = 1;
u16 g_u16_DemoCallId = APPCALL_NO_CALL;
u16 g_u16_DemoCallId_0 = APPCALL_NO_CALL;
u16 g_u16_DemoCallId_1 = APPCALL_NO_CALL;
u16 g_u16_DemoCallId_2 = APPCALL_NO_CALL;
u16 g_u16_DemoCallId_3 = APPCALL_NO_CALL;
u16 g_u16_DemoCallId_4 = APPCALL_NO_CALL;
PST_CMBS_APP_INST appcmbs_get_CMBSAppInstance(void)
{
return &g_CMBSAppInstance;
}
// ========== appcmbs_CallBack ===========
/*!
\brief registered callback function to CMBS API for received events
\param[in] pv_AppRef application reference pointer
\param[in] e_EventID received event ID
\param[in] pv_EventData IE list pointer
\return <none>
*/
void appcmbs_CallBack(void *pv_AppRef, E_CMBS_EVENT_ID e_EventID, void *pv_EventData)
{
unsigned int i;
if ( pv_AppRef )
{} // Just one callback function registered, so we don't have to evaluate pv_AppRef
///////////////////////////////////////////////
// JSystem
#ifdef Q_AUTO
// call the JSystem Callback function
//JSystemCallback(e_EventID, pv_EventData);
///////////////////////////////////////////////////
#else
if(g_fptrHANTargetAliveIndication)
{
g_fptrHANTargetAliveIndication();
}
#endif
for (i = 0; i < (sizeof(g_pfn_app_Entity) / sizeof(PFN_APP_ENTITY_CB)); i++)
{
if ( g_pfn_app_Entity[i] )
{
if ( g_pfn_app_Entity[i](pv_AppRef, e_EventID, pv_EventData) )
{
// no handler is needed anymore, event is consumed
return;
}
}
}
APPCMBS_WARN(("Warning: Event: %d %s is not handled, yet\n", e_EventID, cmbs_dbg_GetEventName(e_EventID)));
}
int appcmbs_CordlessStart(ST_IE_SYPO_SPECIFICATION *SYPOParameters)
{
// Start DECT module
appcmbs_PrepareRecvAdd ( TRUE); // This function must be called before sending messages if you want to wait for event/container.
cmbs_dsr_sys_Start(g_cmbsappl.pv_CMBSRef, SYPOParameters);
return appcmbs_WaitForEvent(CMBS_EV_DSR_SYS_START_RES); // This function must be called only after appcmbs_PrepareRecvAdd ( TRUE)
}
// ========== appcmbs_MaxTransferSizeGet ===========
/*!
\brief short description
\param[in,out] None
\return <int> return Max size of transfer supported by the Target
*/
void appcmbs_MaxTransferSizeGet(void)
{
ST_APPCMBS_CONTAINER st_Container;
u32 u32_temp = 0;
//Get CMBS MAX Buffer size supporetd by target
appcmbs_PrepareRecvAdd ( TRUE); // This function must be called before sending messages if you want to wait for event/container.
app_SrvParamGet(CMBS_PARAM_MAX_TRANSFER_SIZE, 1);
appcmbs_WaitForContainer(CMBS_EV_DSR_PARAM_GET_RES, &st_Container); // This function must be called only after appcmbs_PrepareRecvAdd ( TRUE)
if ( st_Container.n_InfoLen )
{
memcpy(&u32_temp, st_Container.ch_Info, CMBS_PARAM_MAX_TRANSFER_SIZE_LENGTH);
cfr_ie_ser_u32((u8 *)&g_CMBSMaxTransferSize,u32_temp);
}
if ( g_CMBSMaxTransferSize == 0 )
{
// can happen if the target is old and does not support the CMBS_PARAM_MAX_TRANSFER_SIZE parameter
APPCMBS_INFO(("g_CMBSMaxTransferSize setting to default %u", DEFAULT_MAX_TRANSFER_SIZE));
g_CMBSMaxTransferSize = DEFAULT_MAX_TRANSFER_SIZE;
}
}
// ========== appcmbs_Initialize ===========
/*!
\brief short description
\param[in,out] pv_AppReference application pointer reference
\return <int> return zero if successful
*/
E_CMBS_RC appcmbs_Initialize(void *pv_AppReference, PST_CMBS_DEV pst_DevCtl, PST_CMBS_DEV pst_DevMedia, PST_CB_LOG_BUFFER pfn_log_buffer_Cb)
{
E_CMBS_RC e_RC = CMBS_RC_OK;
// reset application
memset(&g_cmbsappl, 0, sizeof(g_cmbsappl));
g_cmbsappl.pv_ApplRef = pv_AppReference;
// initialize application
appcall_Initialize();
app_FacilityInit();
// intercommunication between engine and application
g_cmbsappl.n_MssgAppID = cmbs_api_MsgQCreate();
// initialize CMBS API and register callback function
// for test application
cmbs_api_RegisterLogBufferCb(cmbs_api_get_LogBufferCb(), pfn_log_buffer_Cb);
cmbs_dbg_SetParseIEFunc(app_PrintIe2Log);
if ( (e_RC = cmbs_api_Init(CMBS_MODE_MLB, pst_DevCtl, pst_DevMedia)) == CMBS_RC_OK )
{
APPCMBS_INFO(("APP: INFO CMBS-API started with Module version %04x\n", cmbs_api_ModuleVersionGet()));
if ( (g_cmbsappl.pv_CMBSRef = cmbs_api_RegisterCb(&g_cmbsappl, (PFN_CMBS_API_CB)appcmbs_CallBack, 0x0100)) == NULL )
{
APPCMBS_WARN(("APP: WARN Can't register API callback function\n"));
}
}
else
{
printf("Initialization failed\n");
return e_RC;
}
if ( !u8_APP_LA_Initialized )
{
app_LaInitialize();
u8_APP_LA_Initialized = 1;
}
app_HanMWInitialize();
return e_RC;
}
// ========== appcmbs_Cleanup ===========
/*!
\brief clean up CMBS API layer and CMBS API
\param[in] <none>
\return <none>
*/
void appcmbs_Cleanup(void)
{
APPCMBS_INFO(("APP: INFO Cleanup CMBS connectivity\n"));
cmbs_api_UnInit();
cmbs_api_MsgQDestroy(g_cmbsappl.n_MssgAppID);
List_Close();
}
// ========== app_ResponseCheck ===========
/*!
\brief check the IE response item and return response code
\param[in] pv_List IE list pointer
\return <s8> return response code TRUE/FALSE or -1 in case not finding IE
*/
s8 app_ResponseCheck(void *pv_List)
{
void *pv_IE;
u16 u16_IE;
cmbs_api_ie_GetFirst(pv_List, &pv_IE, &u16_IE);
while (pv_IE != NULL)
{
if ( u16_IE == CMBS_IE_RESPONSE )
{
ST_IE_RESPONSE st_Response;
// check response code:
cmbs_api_ie_ResponseGet(pv_IE, &st_Response);
return st_Response.e_Response;
}
cmbs_api_ie_GetNext(pv_List, &pv_IE, &u16_IE);
}
return -1;
}
// ========== appcmbs_PrepareRecvAdd ===========
/*!
\brief set token to pass received infromation to upper layer
\param[in] u32_Token TRUE for passing
\return <none>
*/
void appcmbs_PrepareRecvAdd(u32 u32_Token)
{
g_cmbsappl.n_Token = (int)u32_Token;
}
#ifdef Q_AUTO
void appcmbs_PrepareRecvAddJSys(u32 u32_Token)
{
g_cmbsappl.j_Token = (int)u32_Token;
}
#endif
// ========== appcmbs_WaitForContainer ===========
/*!
\brief Synchronization function enables the application to wait until
requested CMBS event was received.
\param[in] n_Event wait for this CMBS event
\param[in,out] pst_Container pointer to CMBS information contatiner
\return <int> return TRUE, if received, otherwise FALSE on error
\todo timeout handling has to be integrated
*/
int appcmbs_WaitForContainer(int n_Event, PST_APPCMBS_CONTAINER pst_Container)
{
int nRetVal;
int bo_Run = TRUE;
ST_APPCMBS_LINUX_CONTAINER LinuxContainer;
g_cmbsappl.n_Token = 1;
while (bo_Run)
{
nRetVal = msgrcv(g_cmbsappl.n_MssgAppID, &LinuxContainer, sizeof(ST_APPCMBS_CONTAINER), 0, 0);
if ( nRetVal == -1 )
{
g_cmbsappl.n_Token = 0;
bo_Run = FALSE;
}
else if ( n_Event == LinuxContainer.Content.n_Event )
{
if ( pst_Container )
memcpy(pst_Container, &LinuxContainer.Content, nRetVal);
g_cmbsappl.n_Token = 0;
return TRUE;
}
// timeout handler
}
return FALSE;
}
int appcmbs_WaitForEvent(int n_Event)
{
return appcmbs_WaitForContainer(n_Event, NULL);
}
int appcmbs_ObjectSignalTrace(void)
{
struct msqid_ds ds;
int len = -1;
memset(&ds, 0, sizeof(ds));
if (msgctl(g_cmbsappl.n_MssgAppID, IPC_STAT, &ds) == 0)
len = ds.msg_qnum;
return len;
}
// ========== appcmbs_ObjectSignal ===========
/*!
\brief signal to application of received event
\param[in] psz_Info pointer to information buffer
\param[in] n_InfoLen length of information
\param[in] n_Info additional information, e.g. IE element
\param[in] n_Event received CMBS event
\return <none>
*/
void appcmbs_ObjectSignal(char *psz_Info, int n_InfoLen, int n_Info, int n_Event)
{
int nRetVal;
if ( g_cmbsappl.n_MssgAppID >= 0 )
{
ST_APPCMBS_LINUX_CONTAINER LinuxContainer;
LinuxContainer.mType = 1;
memcpy(LinuxContainer.Content.ch_Info, psz_Info, n_InfoLen);
LinuxContainer.Content.n_InfoLen = n_InfoLen;
LinuxContainer.Content.n_Event = n_Event;
LinuxContainer.Content.n_Info = n_Info;
nRetVal = msgsnd(g_cmbsappl.n_MssgAppID, &LinuxContainer, (3 * (sizeof(int)) + n_InfoLen), 0);
if ( nRetVal == -1 )
{
APPCMBS_ERROR(("App:ERROR !!! Container Object was not sent! %d\n",errno));
}
}
}
// ========== appcmbs_IEInfoGet ===========
/*!
\brief handles general to IE function
\param[in] pv_IE IE buffer
\param[in] u16_IE enumeration of IE
\param[in,out] p_Info pointer to IE object
\return <none>
*/
void appcmbs_IEInfoGet(void *pv_IE, u16 u16_IE, PST_APPCMBS_IEINFO p_Info)
{
switch (u16_IE)
{
case CMBS_IE_CALLERNAME:
cmbs_api_ie_CallerNameGet(pv_IE, &p_Info->Info.st_CallerName);
break;
case CMBS_IE_CALLERPARTY:
cmbs_api_ie_CallerPartyGet(pv_IE, &p_Info->Info.st_CallerParty);
break;
case CMBS_IE_CALLEDPARTY:
cmbs_api_ie_CalledPartyGet(pv_IE, &p_Info->Info.st_CalledParty);
break;
case CMBS_IE_CALLINSTANCE:
cmbs_api_ie_CallInstanceGet(pv_IE, &p_Info->Info.u32_CallInstance);
break;
case CMBS_IE_CALLPROGRESS:
cmbs_api_ie_CallProgressGet(pv_IE, &p_Info->Info.st_CallProgress);
break;
case CMBS_IE_CALLINFO:
cmbs_api_ie_CallInfoGet(pv_IE, &p_Info->Info.st_CallInfo);
break;
case CMBS_IE_MEDIACHANNEL:
cmbs_api_ie_MediaChannelGet(pv_IE, &p_Info->Info.st_MediaChannel);
break;
case CMBS_IE_MEDIADESCRIPTOR:
cmbs_api_ie_MediaDescGet(pv_IE, &p_Info->Info.st_MediaDesc);
break;
case CMBS_IE_CALLRELEASE_REASON:
cmbs_api_ie_CallReleaseReasonGet(pv_IE, &p_Info->Info.st_Reason);
break;
case CMBS_IE_PARAMETER:
cmbs_api_ie_ParameterGet(pv_IE, &p_Info->Info.st_Param);
break;
case CMBS_IE_FW_VERSION:
cmbs_api_ie_FwVersionGet(pv_IE, &p_Info->Info.st_FwVersion);
break;
case CMBS_IE_HW_VERSION:
cmbs_api_ie_HwVersionGet(pv_IE, &p_Info->Info.st_HwVersion);
break;
case CMBS_IE_EEPROM_VERSION:
cmbs_api_ie_EEPROMVersionGet(pv_IE, &p_Info->Info.st_EEPROMVersion);
break;
case CMBS_IE_SYS_LOG:
cmbs_api_ie_SysLogGet(pv_IE, &p_Info->Info.st_SysLog);
break;
case CMBS_IE_SUBSCRIBED_HS_LIST:
cmbs_api_ie_SubscribedHSListGet(pv_IE, &p_Info->Info.st_SubscribedHsList);
break;
case CMBS_IE_LINE_SETTINGS_LIST:
cmbs_api_ie_LineSettingsListGet(pv_IE, &p_Info->Info.st_LineSettingsList);
break;
case CMBS_IE_RESPONSE:
cmbs_api_ie_ResponseGet(pv_IE, &p_Info->Info.st_Resp);
break;
case CMBS_IE_LINE_ID:
cmbs_api_ie_LineIdGet(pv_IE, &p_Info->Info.u8_LineId);
break;
case CMBS_IE_MELODY:
cmbs_api_ie_MelodyGet(pv_IE, &p_Info->Info.u8_Melody);
break;
case CMBS_IE_DECT_SETTINGS_LIST:
cmbs_api_ie_DectSettingsListGet(pv_IE, &p_Info->Info.st_DectSettings);
break;
case CMBS_IE_PROP_FIELDS_LIST:
cmbs_api_ie_PropDectSettingsListGet(pv_IE, &p_Info->Info.st_PropSettings);
break;
case CMBS_IE_CALL_LIST:
cmbs_api_ie_CallListGet(pv_IE, &p_Info->Info.st_CallList);
break;
default:
if ( CMBS_IE_USER_DEFINED_START <= u16_IE && u16_IE <= CMBS_IE_USER_DEFINED_END )
{
break;
}
APPCMBS_WARN(("APP: WARN IE_ToString: IE:%d not implemented\n", u16_IE));
}
}
void appcmbs_VersionGet(char *pc_Version)
{
char ch_RcBuild[20];
u16 u16_Version = cmbs_api_ModuleVersionGet();
u16 u16_Build = cmbs_api_ModuleVersionBuildGet();
if (u16_Build>>8)
{
sprintf (ch_RcBuild,"- RC %u", (u16_Build>>8));
}
else
{
ch_RcBuild[0] = '\0';
}
if ( u16_Version > 0xFFF )
sprintf(pc_Version, "Version %x.%02x.%x - Build %hu %s", (u16_Version >> 12), ((u16_Version >> 4)& 0xFF),(u16_Version & 0xF), (u16_Build & 0xFF), ch_RcBuild);
else
sprintf(pc_Version, "Version %02x.%02x - Build %hu %s", (u16_Version >> 8), (u16_Version & 0xFF), (u16_Build & 0xFF), ch_RcBuild);
}
unsigned long appcmbs_GetTickCount(void)
{
struct timeval tv;
gettimeofday(&tv,NULL);
return ((unsigned long)tv.tv_sec*1000);
}
int appcmbs_ReconnectApplication(unsigned long ulTimeoutMs)
{
u32 u32_Sec, i;
int resp;
u8 u8_HwChip_temp, u8_HwComType_temp;
//effi - need this to re-regsiter the log callbacks
ST_CB_LOG_BUFFER * pfnLogCallbacks=cmbs_api_get_LogBufferCb();
cmbs_api_UnInit();
if ( ulTimeoutMs )
{
u32_Sec = ulTimeoutMs / 1000;
for (i = 0; i <= u32_Sec; ++i)
{
printf("\r%d sec. remaining...", u32_Sec - i);
SleepMs(1000);
}
}
APPCMBS_INFO(("\n"));
// Back and restore u8_HwChip and u8_HwComType since cmbs_api_Init cleans them
u8_HwChip_temp = appcmbs_get_CMBSAppInstance()->u8_HwChip;
u8_HwComType_temp = appcmbs_get_CMBSAppInstance()->u8_HwComType;
resp = cmbs_api_Init(CMBS_MODE_MLB, &g_st_DevCtl, &g_st_DevMedia);
cmbs_api_RegisterCb(&g_cmbsappl, (PFN_CMBS_API_CB)appcmbs_CallBack, 0x0100);
// Effi - need to reregister the log functions
// Register callback functions for log buffer handling
cmbs_api_RegisterLogBufferCb(&g_cmbsappl, pfnLogCallbacks);
cmbs_dbg_SetParseIEFunc(app_PrintIe2Log);
appcmbs_get_CMBSAppInstance()->u8_HwChip = u8_HwChip_temp;
appcmbs_get_CMBSAppInstance()->u8_HwComType = u8_HwComType_temp;
if ( resp == CMBS_RC_OK )
{
cmbs_dsr_sys_Start(g_cmbsappl.pv_CMBSRef, NULL);
}
else
{
APPCMBS_ERROR(("appcmbs_Initialize failure %d!!!", resp));
}
return resp;
}
int app_CmdEntity(void *pv_AppRef, E_CMBS_EVENT_ID e_EventID, void *pv_EventData)
{
UNUSED_PARAMETER(pv_AppRef);
UNUSED_PARAMETER(pv_EventData);
// return TRUE for all commands
return (e_EventID & CMBS_CMD_MASK) == CMBS_CMD_MASK;
}
#ifdef CMBS_PLUGIN
int app_PluginEntity(void *pv_AppRef, E_CMBS_EVENT_ID e_EventID, void *pv_EventData)
{
return CMBS_HandleEventPlugins(pv_AppRef, e_EventID, pv_EventData);
}
#endif
void app_CreateThread(start_routine pfn)
{
pthread_t uTempThread;
pthread_create( &uTempThread, NULL, pfn, (void*) NULL);
}

View File

@@ -0,0 +1,208 @@
/*!
* \file appmain.h
* \brief object and utility declaration
* \Author kelbch
*
* @(#) %filespec: appcmbs.h~13.1.1.1.1.1.10 %
*
*******************************************************************************
* \par History
* \n==== History ============================================================\n
* date name version action \n
* ----------------------------------------------------------------------------\n
*******************************************************************************/
#if !defined( APPCMBS_H )
#define APPCMBS_H
#include "cfr_mssg.h"
#ifndef caseretstr
#define caseretstr(x) case x: return #x
#endif
#if defined ( TCXLOG_FILE )
#include "tcx_hostlog.h"
#define APPCMBS_ERROR(x) GENERAL_LOG_ERROR_PRINT x
#define APPCMBS_WARN(x) GENERAL_LOG_WARNING_PRINT x
#define APPCMBS_INFO(x) GENERAL_LOG_INFO_PRINT x
#define APPCMBS_IE(x) GENERAL_LOG_INFO_PRINT x
#else
#define APPCMBS_ERROR(x) printf x
#define APPCMBS_WARN(x) printf x
#define APPCMBS_INFO(x) printf x
#define APPCMBS_IE(x) printf x
#endif
#define APPCMBS_RECONNECT_TIMEOUT (60000) //60 sec (should be enough for eeprom resetting)
#define HAN_DECT_SUBS_LENGTH (101*1000+5)
#define HAN_ULE_SUBS_LENGTH (15*1000)
#define HAN_FUN_SUBS_LENGTH (131*1000)
#define HAN_FUN_GROUP_LIST_LENGTH (50)
#define HAN_FUN_GROUP_TABLE_LENGTH (500)
#define HAN_ULE_BROADCAST_CONVERSION_TABLE_LENGTH (600)
#define PARAM_REPEATER_SUBS_DATA_LENGTH 50*28 //50 bytes per Repeater and handset over repeater, 28 in maximum case
typedef void* (*start_routine)(void *);
typedef struct
{
E_CMBS_IE_TYPE e_IE;
union
{
u32 u32_CallInstance;
u8 u8_LineId;
ST_IE_CALLEDPARTY st_CalledParty;
ST_IE_CALLERPARTY st_CallerParty;
ST_IE_CALLERNAME st_CallerName;
ST_IE_CALLPROGRESS st_CallProgress;
ST_IE_CALLINFO st_CallInfo;
ST_IE_DISPLAY_STRING st_DisplayString;
ST_IE_RELEASE_REASON st_Reason;
ST_IE_MEDIA_DESCRIPTOR st_MediaDesc;
ST_IE_MEDIA_CHANNEL st_MediaChannel;
ST_IE_TONE st_Tone;
ST_IE_TIMEOFDAY st_Time;
ST_IE_HANDSETINFO st_HandsetInfo;
ST_IE_PARAMETER st_Param;
ST_IE_FW_VERSION st_FwVersion;
ST_IE_HW_VERSION st_HwVersion;
ST_IE_SYS_LOG st_SysLog;
ST_IE_SUBSCRIBED_HS_LIST st_SubscribedHsList;
ST_IE_LINE_SETTINGS_LIST st_LineSettingsList;
ST_IE_DECT_SETTINGS_LIST st_DectSettings;
ST_IE_PROP_FIELDS_LIST st_PropSettings;
ST_IE_USER_DEFINED st_UserDefined;
ST_IE_RESPONSE st_Resp;
// ST_IE_STATUS st_Status;
u32 u32_IntegerValue;
u8 u8_Melody;
ST_IE_EEPROM_VERSION st_EEPROMVersion;
ST_IE_CALL_LIST st_CallList;
}Info;
} ST_APPCMBS_IEINFO, *PST_APPCMBS_IEINFO;
typedef struct
{
void *pv_ApplRef;
void *pv_CMBSRef;
int n_MssgAppID;
int n_Token;
#ifdef Q_AUTO
int j_Token;
#endif
int RegistrationWindowStatus; // 0 - Closed, 1 - Opened
}ST_CMBS_APPL, *PST_CMBS_APPL;
typedef struct
{
int n_InfoLen;
int n_Info;
int n_Event;
char ch_Info[4*1024];
} ST_APPCMBS_CONTAINER, *PST_APPCMBS_CONTAINER;
typedef union {
u8 pu8_HAN_DECT_DATA[HAN_DECT_SUBS_LENGTH];
u8 pu8_HAN_ULE_DATA[HAN_ULE_SUBS_LENGTH];
u8 pu8_HAN_FUN_DATA[HAN_FUN_SUBS_LENGTH];
u8 pu8_HAN_FUN_GROUP_LIST_DATA[HAN_FUN_GROUP_LIST_LENGTH];
u8 pu8_HAN_FUN_GROUP_TABLE_DATA[HAN_FUN_GROUP_TABLE_LENGTH];
u8 pu8_HAN_ULE_BROADCAST_CONVERSION_TABLE_DATA[HAN_ULE_BROADCAST_CONVERSION_TABLE_LENGTH];
u8 pu8_HAN_ULE_MULTICAST_ENC_PARAMS_DATA[CMBS_PARAM_ULE_MULTICAST_ENC_PARAMS_LENGTH];
u8 pu8_REPEATER_SUBS_DATA[PARAM_REPEATER_SUBS_DATA_LENGTH];
} UnionHanEEPROMBackupEBlocksPools;
typedef struct
{
long mType;
ST_APPCMBS_CONTAINER Content;
} ST_APPCMBS_LINUX_CONTAINER, *PST_APPCMBS_LINUX_CONTAINER;
typedef struct
{
E_CMBS_HW_CHIP u8_HwChip; /*!< HW chip */
E_CMBS_HW_CHIP_VERSION u8_HwChipVersion; /*!< HW chip version */
E_CMBS_HW_BOARD u8_HwBoard; /*!< HW board type */
E_CMBS_HW_COM_TYPE u8_HwComType; /*!< HW communication */
} ST_CMBS_APP_INST, *PST_CMBS_APP_INST;
typedef enum
{
NO_EXTERNAL_CLIENT,
EXTERNAL_CLIENT_EXIST
}t_e_ExternalClient;
typedef u32(*t_fptrHANTargetAliveIndication)();
extern ST_CMBS_APPL g_cmbsappl;
#if defined( __cplusplus )
extern "C"
{
#endif
s8 app_ResponseCheck(void *pv_List);
u8 app_ASC2HEX(char *psz_Digits);
void keyb_ParamAreaGetBySegments(u32 u32_Pos, u32 u32_Length, u8 *pu8_Data, u32 packet_max_size);
void keyb_ParamAreaSetBySegments(u32 u32_Pos, u32 u32_Length, u8 *pu8_Data, u16 packet_max_size);
E_CMBS_RC keyb_ParamAreaGetFromFile(u8 *pu8_Data, u8 *pu8_path);
t_e_ExternalClient appcmbs_GetExternalClientInformation();
void appcmbs_SetExternalClientInformation(t_e_ExternalClient client);
//callback for target alive indication
void appcmbs_RegisterTargetAliveIndicationCB(t_fptrHANTargetAliveIndication fpt_registerCallBackForTargetAliveIndication);
// callback for CMBS responses according specification
int app_ServiceEntity(void *pv_AppRef, E_CMBS_EVENT_ID e_EventID, void *pv_EventData);
int app_CallEntity(void *pv_AppRef, E_CMBS_EVENT_ID e_EventID, void *pv_EventData);
int app_SwupEntity(void *pv_AppRef, E_CMBS_EVENT_ID e_EventID, void *pv_EventData);
int app_FacilityEntity(void *pv_AppRef, E_CMBS_EVENT_ID e_EventID, void *pv_EventData);
int app_DataEntity(void *pv_AppRef, E_CMBS_EVENT_ID e_EventID, void *pv_EventData);
int app_LaEntity(void *pv_AppRef, E_CMBS_EVENT_ID e_EventID, void *pv_EventData);
int app_UleDataEntity(void * pv_AppRef, E_CMBS_EVENT_ID e_EventID, void * pv_EventData);
int app_SuotaEntity(void *pv_AppRef, E_CMBS_EVENT_ID e_EventID, void *pv_EventData);
int app_SuotaFileEntity(void *pv_AppRef, E_CMBS_EVENT_ID e_EventID, void *pv_EventData);
int app_RTPEntity(void *pv_AppRef, E_CMBS_EVENT_ID e_EventID, void *pv_EventData);
int app_HANEntity(void *pv_AppRef, E_CMBS_EVENT_ID e_EventID, void *pv_EventData);
int app_CmdEntity(void *pv_AppRef, E_CMBS_EVENT_ID e_EventID, void *pv_EventData);
int app_PluginEntity(void *pv_AppRef, E_CMBS_EVENT_ID e_EventID, void *pv_EventData);
#if defined (CRASH_DUMP)
int app_CrashDumpEntity(void *pv_AppRef, E_CMBS_EVENT_ID e_EventID, void *pv_EventData);
#endif
// initialize the CMBS application
E_CMBS_RC appcmbs_Initialize(void *pv_AppReference, PST_CMBS_DEV pst_DevCtl, PST_CMBS_DEV pst_DevMedia, PST_CB_LOG_BUFFER pfn_log_buffer_Cb);
void appcmbs_Cleanup(void);
void appcmbs_InitEeprom(u8 *pu8_EEprom, u16 u16_Size);
int appcmbs_CordlessStart(ST_IE_SYPO_SPECIFICATION *SYPOParameters);
// synchronize upper application with async CMBS received Data
int appcmbs_ObjectSignalTrace(void);
void appcmbs_ObjectSignal(char *psz_Info, int n_InfoLen, int n_Info, int n_Event);
void appcmbs_PrepareRecvAdd(u32 u32_Token);
int appcmbs_WaitForContainer(int n_Event, PST_APPCMBS_CONTAINER pst_Container);
int appcmbs_WaitForEvent(int n_Event);
void appcmbs_IEInfoGet(void *pv_IE, u16 u16_IE, PST_APPCMBS_IEINFO p_Info);
void appcmbs_VersionGet(char *pc_Version);
unsigned long appcmbs_GetTickCount(void);
int appcmbs_ReconnectApplication(unsigned long ulTimeoutMs);
void app_CreateThread(start_routine);
PST_CMBS_APP_INST appcmbs_get_CMBSAppInstance(void);
void appcmbs_MaxTransferSizeGet(void);
#if defined( __cplusplus )
}
#endif
#endif // APPCMBS_H

View File

@@ -0,0 +1,380 @@
/*!
* \file appcrashdump.c
* \brief useful to collect the ram dump during cmbs crash
* \Author hareeshk
*
* @(#) %filespec: appcrashdump.c
*
*******************************************************************************
* \par History
* \n==== History ============================================================\n
* date name version action \n
* ----------------------------------------------------------------------------\n
*
*******************************************************************************/
#if ! defined ( WIN32 )
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <sys/time.h>
#include <signal.h>
#include <string.h>
#endif
#include "stdio.h"
#include "cmbs_api.h"
#include "cfr_mssg.h"
#include "cmbs_fifo.h"
#include "appcmbs.h"
#include "appcrashdump.h"
FILE *g_fpCDFile = NULL;
#define DEBUG_CRASHDUMP
u32 g_CDPacketNr = 0;
u32 g_CDTotalPackets = 0;
void app_CrashDumpRequestNextPacket(void);
/************************ APP Crash Dump Common APIs to Map CMBS APIs**********************/
void app_ConfigCrashDump(E_CRASH_DUMP_ENABLE_STATUS u8_EnableStatus)
{
cmbs_dsr_ConfigCrashDump(g_cmbsappl.pv_CMBSRef, u8_EnableStatus);
}
void app_ReadCrashDumpConfig(void)
{
cmbs_dsr_ReadCrashDumpConfig(g_cmbsappl.pv_CMBSRef);
}
void app_CrashDumpStart(void)
{
cmbs_dsr_CrashDumpStart(g_cmbsappl.pv_CMBSRef);
}
void app_CrashDumpPacketSend(PST_IE_PACKET_NUMBER pst_PktNr)
{
cmbs_dsr_CrashDumpDataPacketSend(g_cmbsappl.pv_CMBSRef, pst_PktNr);
}
void app_CrashDumpSendDataPacketRes(ST_IE_RESPONSE st_Response)
{
cmbs_dsr_CrashDumpDataPacketSendRes(g_cmbsappl.pv_CMBSRef, st_Response);
}
void app_CrashDumpEnd(void)
{
cmbs_dsr_CrashDumpEnd(g_cmbsappl.pv_CMBSRef);
}
void app_CrashDumpSendEndRes(ST_IE_RESPONSE st_Response)
{
cmbs_dsr_CrashDumpEndRes(g_cmbsappl.pv_CMBSRef, st_Response);
}
/************************ APP Crash Dump routines **********************/
void app_CrashDumpProcStart(void)
{
char filename[20] = { 0 };
g_fpCDFile = fopen("crash.bin", "wb");
if ( g_fpCDFile == NULL )
{
printf("[Crash Dump] File creation error\n\n");
return;
}
else
{
printf("[Crash Dump] File created successfully. File name: %s\n\n", filename);
}
app_CrashDumpStart();
}
void app_OnCrashDumpStartRes(void *pvAppRefHandle, void *pv_List)
{
ST_IE_RESPONSE st_Response;
ST_IE_PACKET_NUMBER st_PktNr;
void *pv_IE = NULL;
u16 u16_IE;
E_CMBS_RC e_rc = CMBS_RC_MAX;
UNUSED_PARAMETER(pvAppRefHandle);
memset(&st_PktNr, 0x00, sizeof(st_PktNr));
st_Response.e_Response = CMBS_RESPONSE_ERROR;
if(pv_List)
{
cmbs_api_ie_GetFirst(pv_List, &pv_IE, &u16_IE);
while (pv_IE != NULL)
{
switch (u16_IE)
{
case CMBS_IE_RESPONSE:
e_rc = cmbs_api_ie_ResponseGet(pv_IE, &st_Response);
break;
case CMBS_IE_PACKET_NUMBER:
e_rc = cmbs_api_ie_PacketNumberGet(pv_IE, &st_PktNr);
break;
}
cmbs_api_ie_GetNext(pv_List, &pv_IE, &u16_IE);
}
if ((st_Response.e_Response != CMBS_RESPONSE_OK) || (e_rc != CMBS_RC_OK) || (st_PktNr.u16_TotalPkts == 0))
{
printf("app_OnCrashDumpStartRes: Response Error. Closing the file \n");
if (g_fpCDFile)
{
fclose(g_fpCDFile);
g_fpCDFile = NULL;
}
return;
}
printf("app_OnCrashDumpStartRes: CrashDump Procedure started successfully\n");
}
g_CDPacketNr=0;
g_CDTotalPackets = st_PktNr.u16_TotalPkts;
#if defined(CRASH_DUMP_IN_HOST_CONTROL)
app_CrashDumpRequestNextPacket(); /* To request for the next packet*/
#endif
}
#if defined(CRASH_DUMP_IN_HOST_CONTROL)
void app_CrashDumpRequestNextPacket(void)
{
ST_IE_PACKET_NUMBER st_PktNr;
st_PktNr.u16_PktNr = ++g_CDPacketNr; //Increment the packet number
st_PktNr.u16_TotalPkts = g_CDTotalPackets;
if(g_CDPacketNr <= g_CDTotalPackets)
{
app_CrashDumpPacketSend(&st_PktNr);
}
else
{
app_CrashDumpEnd();
}
}
void app_OnCrashDumpDataPacketSendRes(void *pvAppRefHandle, void *pv_Param)
{
ST_IE_RESPONSE st_Response;
ST_IE_DATA st_Data;
void *pv_IE = NULL;
u16 u16_IE;
UNUSED_PARAMETER(pvAppRefHandle);
st_Response.e_Response = CMBS_RESPONSE_ERROR;
memset(&st_Data,0x00, sizeof(ST_IE_DATA));
if(pv_Param)
{
cmbs_api_ie_GetFirst(pv_Param, &pv_IE, &u16_IE);
while (pv_IE != NULL)
{
switch (u16_IE)
{
case CMBS_IE_DATA:
cmbs_api_ie_DataGet(pv_IE, &st_Data);
break;
}
cmbs_api_ie_GetNext(pv_Param, &pv_IE, &u16_IE);
}
}
if(g_fpCDFile && st_Data.pu8_Data && st_Data.u16_DataLen &&
(st_Data.u16_DataLen <= 512))
{
u32 u32_cnt;
u32_cnt = fwrite(st_Data.pu8_Data, 1, st_Data.u16_DataLen, g_fpCDFile);
if(u32_cnt == st_Data.u16_DataLen)
{
st_Response.e_Response = CMBS_RESPONSE_OK;
}
else
{
printf("app_OnCrashDumpPacketSend: Write Fail Invalid length. Closing the file\n");
fclose(g_fpCDFile);
g_fpCDFile = NULL;
}
}
else
{
if(!g_fpCDFile)
printf("app_OnCrashDumpPacketSend: Error File was not created. Closing the file\n");
else
printf("app_OnCrashDumpPacketSend: Error in received data length. Closing the file\n");
if (g_fpCDFile)
{
fclose(g_fpCDFile);
g_fpCDFile = NULL;
}
}
if(st_Response.e_Response == CMBS_RESPONSE_OK)
{
app_CrashDumpRequestNextPacket();
}
else
{
app_CrashDumpEnd();
}
}
void app_OnCrashDumpEndRes(void *pvAppRefHandle, void *pv_Param)
{
UNUSED_PARAMETER(pvAppRefHandle);
UNUSED_PARAMETER(pv_Param);
if (g_fpCDFile)
{
fclose(g_fpCDFile);
g_fpCDFile = NULL;
}
g_CDPacketNr=0;
}
#else /* ELSE of CRASH_DUMP_IN_HOST_CONTROL*/
void app_OnCrashDumpPacketSend(void *pvAppRefHandle, void *pv_Param)
{
ST_IE_PACKET_NUMBER st_PktNr;
ST_IE_DATA st_Data;
void *pv_IE = NULL;
u16 u16_IE;
UNUSED_PARAMETER(pvAppRefHandle);
memset(&st_Data,0x00, sizeof(ST_IE_DATA));
memset(&st_PktNr,0x00, sizeof(ST_IE_PACKET_NUMBER));
if(pv_Param)
{
cmbs_api_ie_GetFirst(pv_Param, &pv_IE, &u16_IE);
while (pv_IE != NULL)
{
switch (u16_IE)
{
case CMBS_IE_PACKET_NUMBER:
cmbs_api_ie_PacketNumberGet(pv_IE, &st_PktNr);
break;
case CMBS_IE_DATA:
cmbs_api_ie_DataGet(pv_IE, &st_Data);
break;
}
cmbs_api_ie_GetNext(pv_Param, &pv_IE, &u16_IE);
}
}
if(g_fpCDFile && st_Data.pu8_Data && st_Data.u16_DataLen &&
(st_Data.u16_DataLen <= 512))
{
u32 u32_cnt;
u32_cnt = fwrite(st_Data.pu8_Data, 1, st_Data.u16_DataLen, g_fpCDFile);
if(u32_cnt != st_Data.u16_DataLen)
{
printf("app_OnCrashDumpPacketSend: Write Fail Invalid length. Closing the file\n");
fclose(g_fpCDFile);
g_fpCDFile = NULL;
}
}
else
{
if(!g_fpCDFile)
printf("app_OnCrashDumpPacketSend: Error File was not created. Closing the file\n");
else
printf("app_OnCrashDumpPacketSend: Error in received data length. Closing the file\n");
if (g_fpCDFile)
{
fclose(g_fpCDFile);
g_fpCDFile = NULL;
}
}
//app_CrashDumpSendDataPacketRes(st_Response);
}
void app_OnCrashDumpEnd(void *pvAppRefHandle, void *pv_List)
{
ST_IE_RESPONSE st_Response;
UNUSED_PARAMETER(pvAppRefHandle);
UNUSED_PARAMETER(pv_List);
st_Response.e_Response= CMBS_RESPONSE_ERROR;
if (g_fpCDFile)
{
fclose(g_fpCDFile);
g_fpCDFile = NULL;
st_Response.e_Response= CMBS_RESPONSE_OK;
}
g_CDPacketNr=0;
app_CrashDumpSendEndRes(st_Response);
}
#endif /*CRASH_DUMP_IN_HOST_CONTROL*/
// ========== app_CrashDumpEntity ===========
/*!
\brief dispatcher fo Crash Dump CMBS events
\param[in] pv_AppRef application reference pointer
\param[in] e_EventID received CMBS event
\param[in] pv_EventData pointer to IE list
\return <int> TRUE, if consumed
*/
int app_CrashDumpEntity(void *pv_AppRef, E_CMBS_EVENT_ID e_EventID, void *pv_EventData)
{
switch (e_EventID)
{
case CMBS_EV_DSR_CRASH_DUMP_START_RES:
app_OnCrashDumpStartRes(pv_AppRef, pv_EventData);
break;
#if defined(CRASH_DUMP_IN_HOST_CONTROL)
case CMBS_EV_DSR_CRASH_DUMP_PACKETSEND_RES:
app_OnCrashDumpDataPacketSendRes(pv_AppRef, pv_EventData);
break;
case CMBS_EV_DSR_CRASH_DUMP_END_RES:
app_OnCrashDumpEndRes(pv_AppRef, pv_EventData);
break;
#else
case CMBS_EV_DSR_CRASH_DUMP_PACKETSEND:
app_OnCrashDumpPacketSend(pv_AppRef, pv_EventData);
break;
case CMBS_EV_DSR_CRASH_DUMP_END:
app_OnCrashDumpEnd(pv_AppRef, pv_EventData);
break;
#endif
default:
return FALSE;
}
return TRUE;
}

View File

@@ -0,0 +1,31 @@
/*!
* \file appcrashdump.h
* \brief
* \Author hareeshk
*
* @(#) %filespec: appcrashdump. %
*
*******************************************************************************
* \par History
* \n==== History ============================================================\n
* date name version action \n
* ----------------------------------------------------------------------------\n
*******************************************************************************/
#if !defined( APPFACILITY_H )
#define APPCRASHDUMP_H
#if defined( __cplusplus )
extern "C"
{
#endif
extern void app_ConfigCrashDump(E_CRASH_DUMP_ENABLE_STATUS u8_EnableStatus);
extern void app_ReadCrashDumpConfig(void);
extern void app_CrashDumpProcStart(void);
#if defined( __cplusplus )
}
#endif
#endif //APPFACILITY_H
//*/

View File

@@ -0,0 +1,140 @@
/*!
* \file appdata.c
* \brief handles CAT-iq data functioality
* \Author stein
*
* @(#) %filespec: appdata.c~10 %
*
*******************************************************************************
* \par History
* \n==== History ============================================================\n
* date name version action \n
* ----------------------------------------------------------------------------\n
*
*******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if ! defined ( WIN32 )
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/time.h>
#include <signal.h>
#endif
#include "cmbs_int.h"
#include "cmbs_api.h"
#include "cfr_ie.h"
#include "cfr_mssg.h"
#include "appcmbs.h"
#include "appmsgparser.h"
extern u16 app_HandsetMap( char * psz_Handsets );
E_CMBS_RC app_OnDataSessionOpen(void *pvAppRefHandle, void *pv_Param)
{
ST_IE_RESPONSE st_Response;
ST_IE_DATA st_Data;
void *pv_IE = NULL;
u16 u16_IE;
u16 u16_SessionId = 0;
PST_CFR_IE_LIST p_List = (PST_CFR_IE_LIST)cmbs_api_ie_GetList();
st_Data.u16_DataLen = 0;
if(pv_Param)
{
cmbs_api_ie_GetFirst(pv_Param, &pv_IE, &u16_IE);
while (pv_IE != NULL)
{
switch (u16_IE)
{
case CMBS_IE_DATA:
cmbs_api_ie_DataGet(pv_IE, &st_Data);
break;
case CMBS_IE_DATA_SESSION_ID:
cmbs_api_ie_ShortValueGet( pv_IE, &u16_SessionId, CMBS_IE_DATA_SESSION_ID );
break;
}
cmbs_api_ie_GetNext(pv_Param, &pv_IE, &u16_IE);
}
}
if (st_Data.u16_DataLen > 0)
{
if (((st_Data.pu8_Data[1] & 0x0f) == 0x00) && (st_Data.pu8_Data[6] == 0x80) && (st_Data.pu8_Data[7] == 0x01))
{//No IWU_ATTR_PROFSUBTYPE_GMEP & Application os 0x80 01, Simple Data call not SOUTA session
cmbs_api_ie_ShortValueAdd( p_List, u16_SessionId, CMBS_IE_DATA_SESSION_ID );
st_Response.e_Response = CMBS_RESPONSE_OK;
cmbs_api_ie_ResponseAdd( p_List, &st_Response );
cmbs_int_EventSend( CMBS_EV_DSR_HS_DATA_SESSION_OPEN_RES, p_List->pu8_Buffer, p_List->u16_CurSize );
return CMBS_RC_OK;
}
}
return CMBS_RC_OK;
}
E_CMBS_RC app_DataSessionOpen( char * psz_Handset )
{
ST_DATA_SESSION_TYPE
st_DataSessionType;
u16 u16_Handset = app_HandsetMap( psz_Handset );
st_DataSessionType.e_ChannelType = CMBS_DATA_CHANNEL_IWU;
st_DataSessionType.e_ServiceType = CMBS_DATA_SERVICE_TRANSPARENT;
return cmbs_dsr_hs_DataSessionOpen( g_cmbsappl.pv_CMBSRef,
&st_DataSessionType,
u16_Handset );
}
E_CMBS_RC app_DataSend( u16 u16_SessionId, ST_IE_DATA * pst_Data )
{
return cmbs_dsr_hs_DataSend( g_cmbsappl.pv_CMBSRef,
u16_SessionId, pst_Data->pu8_Data, pst_Data->u16_DataLen );
}
E_CMBS_RC app_DataSessionClose( u16 u16_SessionId )
{
return cmbs_dsr_hs_DataSessionClose( g_cmbsappl.pv_CMBSRef,
u16_SessionId );
}
// ========== app_DataEntity ===========
/*!
\brief CMBS entity to handle response information from target side
\param[in] pv_AppRef application reference
\param[in] e_EventID received CMBS event
\param[in] pv_EventData pointer to IE list
\return <int>
*/
int app_DataEntity( void * pv_AppRef, E_CMBS_EVENT_ID e_EventID, void * pv_EventData )
{
UNUSED_PARAMETER( pv_AppRef );
UNUSED_PARAMETER( pv_EventData );
if( e_EventID == CMBS_EV_DSR_HS_DATA_SESSION_OPEN )
{//Call New Fn here
app_OnDataSessionOpen(pv_AppRef,pv_EventData);
return TRUE;
}else if( e_EventID == CMBS_EV_DSR_HS_DATA_SESSION_OPEN_RES ||
e_EventID == CMBS_EV_DSR_HS_DATA_SESSION_CLOSE ||
e_EventID == CMBS_EV_DSR_HS_DATA_SESSION_CLOSE_RES ||
e_EventID == CMBS_EV_DSR_HS_DATA_SEND ||
e_EventID == CMBS_EV_DSR_HS_DATA_SEND_RES )
{
return TRUE;
}
else
return FALSE;
}
//*/

View File

@@ -0,0 +1,33 @@
/*!
* \file appdata.h
* \brief
* \Author stein
*
* @(#) %filespec: appdata.h~DMZD53#5 %
*
*******************************************************************************
* \par History
* \n==== History ============================================================\n
* date name version action \n
* ----------------------------------------------------------------------------\n
*******************************************************************************/
#if !defined( APPCATIQ_H )
#define APPCATIQ_H
#if defined( __cplusplus )
extern "C"
{
#endif
E_CMBS_RC app_DataSessionOpen( char * psz_Handset );
E_CMBS_RC app_DataSend( u16 u16_SessionId, ST_IE_DATA * pst_Data );
E_CMBS_RC app_DataSessionClose( u16 u16_SessionId );
#if defined( __cplusplus )
}
#endif
#endif //APPCATIQ_H
//*/

View File

@@ -0,0 +1,720 @@
/*!
* \file appfacility.c
* \brief handles CAT-iq facilities functionality
* \Author stein
*
* @(#) %filespec: appfacility.c~10 %
*
*******************************************************************************
* \par History
* \n==== History ============================================================\n
* date name version action \n
* ----------------------------------------------------------------------------\n
*
*******************************************************************************/
#if ! defined ( WIN32 )
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/time.h>
#include <signal.h>
#include <string.h>
#endif
#include "cmbs_api.h"
#include "cfr_mssg.h"
#include "cmbs_fifo.h"
#include "appcmbs.h"
#include "stdio.h"
#include "appfacility.h"
#include "cmbs_util.h"
#define MAX_FACILITY_MSG_FOR_HS 10
#define NEW_MSG_ADDED 1
#define MSG_SEND_RESPONSE 0
extern u16 app_HandsetMap(char *psz_Handsets);
/* Data structures for Fifo handling */
typedef struct
{
u16 u16_RequestId;
u8 u8_LineId;
u16 u16_Messages;
E_CMBS_MWI_TYPE eType;
} ST_APP_FACILITY_MWI;
typedef struct
{
u16 u16_RequestId;
u8 u8_LineId;
u16 u16_NewMissedCalls;
bool bNewMissedCall;
u16 u16_TotalMissedCalls;
} ST_APP_FACILITY_MCN;
typedef struct
{
u16 u16_RequestId;
u8 u8_ListId;
u8 u8_ListEntries;
u8 u8_LineId;
u8 u8_LineSubtype;
ST_APP_FACILITY_LCN_DETAILS st_Details;
} ST_APP_FACILITY_LCN;
typedef struct
{
u16 u16_RequestId;
u8 u8_NumOfWebCont;
} ST_APP_FACILITY_WC;
typedef struct
{
u16 u16_RequestId;
u16 u16_Reserved;
u8 pu8_Data[CMBS_PROP_EVENT_LENGTH];
u8 u8_DataLen;
} ST_APP_FACILITY_PROP;
typedef struct
{
u16 u16_RequestId;
ST_DATE_TIME st_DateTime;
} ST_APP_FACILITY_DT;
typedef struct
{
u16 u16_RequestId;
u8 u8_LineId;
u32 u32_LineUseStatus;
} ST_APP_FACILITY_LUI;
typedef struct
{
u16 u16_RequestId;
u8 u8_LineId;
} ST_APP_FACILITY_HUI;
typedef struct
{
u16 u16_RequestId;
u8 u8_LineId;
u8 u8_Type;
} ST_APP_FACILITY_DI;
typedef struct
{
u16 u16_RequestId;
u8 u8_SMSType;
u16 u16_TotalNumOfMsgs;
u16 u16_NumOfUnreadMsgs;
}ST_APP_FACILITY_SMS;
typedef struct
{
u16 u16_RequestId;
u16 u16_PropEvent;
u8 pu8_Data[CMBS_PROP_EVENT_LENGTH];
u8 u8_DataLen;
} ST_APP_FACILITY_PROP_EVENT_NOTIFICATION;
typedef enum
{
FACILITY_TYPE_MWI,
FACILITY_TYPE_MISSED_CALL,
FACILITY_TYPE_LIST_CHANGED,
FACILITY_TYPE_WEB_CONTENT,
FACILITY_TYPE_PROP_EVENT,
FACILITY_TYPE_DATE_TIME,
FACILITY_TYPE_LINE_USE,
FACILITY_TYPE_HANDSET_USE,
FACILITY_TYPE_DIAGNOSTICS,
FACILITY_TYPE_SMS,
FACILITY_PROP_EVENT_NOTIFICATION,
FACILITY_TYPE_LIST_CHANGED_EX
} E_APP_FACILITY_TYPE;
typedef union
{
ST_APP_FACILITY_MWI st_MWI;
ST_APP_FACILITY_MCN st_MCN;
ST_APP_FACILITY_LCN st_LCN;
ST_APP_FACILITY_WC st_WC;
ST_APP_FACILITY_PROP st_PROP;
ST_APP_FACILITY_DT st_DT;
ST_APP_FACILITY_LUI st_LUI;
ST_APP_FACILITY_HUI st_HUI;
ST_APP_FACILITY_DI st_DI;
ST_APP_FACILITY_SMS st_SMS;
ST_APP_FACILITY_PROP_EVENT_NOTIFICATION st_PropEventNotify;
} U_APP_FACILITY_MSG;
typedef struct
{
E_APP_FACILITY_TYPE e_type;
u16 u16_Handsets;
U_APP_FACILITY_MSG u_msg;
} ST_APP_FACILITY_MSG;
static CFR_CMBS_CRITICALSECTION FifoCriticalSection;
ST_CMBS_FIFO app_FacilityFifos[CMBS_HS_SUBSCRIBED_MAX_NUM];
u8 app_FacilityBuffers[CMBS_HS_SUBSCRIBED_MAX_NUM][sizeof(ST_APP_FACILITY_MSG)* MAX_FACILITY_MSG_FOR_HS];
u16 g_u16_BlockHsMask=0;
u16 app_HsMask2HsNum(u16 u16_HsMask);
static E_CMBS_RC app_Facility_PushToFifos(ST_APP_FACILITY_MSG *pst_msg)
{
u8 handset;
u16 handsetMask;
if ( !pst_msg )
{
APP_FACILITY_ERROR_PRINT("app_Facility_PushToFifos NULL pointer provided\n");
return CMBS_RC_ERROR_PARAMETER;
}
handsetMask = pst_msg->u16_Handsets;
for (handset = 0; handset < CMBS_HS_SUBSCRIBED_MAX_NUM; ++handset)
{
if ( (1 << handset) & handsetMask )
{
pst_msg->u16_Handsets = (1 << handset);
if ( !cmbs_util_FifoPush(&app_FacilityFifos[handset], pst_msg) )
{
APP_FACILITY_ERROR_PRINT("FIFO %hhu full !!\n", handset);
}
}
}
return CMBS_RC_OK;
}
static E_CMBS_RC app_Facility_SendToTarget(u16 u16_HsMask, bool bReason)
{
u8 handset;
APP_FACILITY_ERROR_PRINT("app_Facility_SendToTarget u16_HsMask<%hu> bReason<%u>\n", u16_HsMask,(u32)bReason);
// Remove blocked HS Mask, This is to temporarily stop facility to some handsets.
u16_HsMask &= ~(g_u16_BlockHsMask);
if ( !u16_HsMask )
{
return CMBS_RC_OK;
}
for (handset = 0; handset < CMBS_HS_SUBSCRIBED_MAX_NUM; ++handset)
{
if ( (1 << handset) & u16_HsMask )
{
bool bSendMsg = FALSE;
// if the fifo is of size 1 and we entered this function because of new message added, we can send it immediately
if ( bReason == NEW_MSG_ADDED )
{
if ( cmbs_util_FifoCount(&app_FacilityFifos[handset]) == 1 )
bSendMsg = TRUE;
}
// if we have messages in the fifo and we entered this function becasue transmission of previous message is over, we can send another message
else if ( cmbs_util_FifoCount(&app_FacilityFifos[handset]) )
{
bSendMsg = TRUE;
}
if ( bSendMsg )
{
E_CMBS_RC u8_return = CMBS_RC_OK;
ST_APP_FACILITY_MSG *pst_Msg = cmbs_util_FifoGet(&app_FacilityFifos[handset]);
if ( !pst_Msg )
{
APP_FACILITY_ERROR_PRINT("app_Facility_SendToTarget failed getting a message from FIFO %hhu\n", handset);
return CMBS_RC_ERROR_PARAMETER;
}
switch (pst_Msg->e_type)
{
case FACILITY_TYPE_MWI:
APP_FACILITY_INFO_PRINT("Sending MWI\n");
u8_return = cmbs_dsr_gen_SendMWI(g_cmbsappl.pv_CMBSRef, pst_Msg->u_msg.st_MWI.u16_RequestId, pst_Msg->u_msg.st_MWI.u8_LineId,
pst_Msg->u16_Handsets, pst_Msg->u_msg.st_MWI.u16_Messages, pst_Msg->u_msg.st_MWI.eType);
break;
case FACILITY_TYPE_MISSED_CALL:
APP_FACILITY_INFO_PRINT("Sending MISSED CALL NOTIF\n");
u8_return = cmbs_dsr_gen_SendMissedCalls(g_cmbsappl.pv_CMBSRef, pst_Msg->u_msg.st_MCN.u16_RequestId, pst_Msg->u_msg.st_MCN.u8_LineId, pst_Msg->u16_Handsets, pst_Msg->u_msg.st_MCN.u16_NewMissedCalls,
pst_Msg->u_msg.st_MCN.bNewMissedCall, pst_Msg->u_msg.st_MCN.u16_TotalMissedCalls);
break;
case FACILITY_TYPE_LIST_CHANGED:
APP_FACILITY_INFO_PRINT("Sending LIST CHANGED NOTIF\n");
u8_return = cmbs_dsr_gen_SendListChanged(g_cmbsappl.pv_CMBSRef, pst_Msg->u_msg.st_LCN.u16_RequestId, pst_Msg->u16_Handsets,
pst_Msg->u_msg.st_LCN.u8_ListId, pst_Msg->u_msg.st_LCN.u8_ListEntries, pst_Msg->u_msg.st_LCN.u8_LineId, pst_Msg->u_msg.st_LCN.u8_LineSubtype);
break;
case FACILITY_TYPE_WEB_CONTENT:
APP_FACILITY_INFO_PRINT("Sending WEB CONTENT\n");
u8_return = cmbs_dsr_gen_SendWebContent(g_cmbsappl.pv_CMBSRef, pst_Msg->u_msg.st_WC.u16_RequestId, pst_Msg->u16_Handsets, pst_Msg->u_msg.st_WC.u8_NumOfWebCont);
break;
case FACILITY_TYPE_PROP_EVENT:
APP_FACILITY_INFO_PRINT("Sending PROP. EVENT\n");
u8_return = cmbs_dsr_gen_SendPropEvent(g_cmbsappl.pv_CMBSRef, pst_Msg->u_msg.st_PROP.u16_RequestId, pst_Msg->u_msg.st_PROP.u16_Reserved, pst_Msg->u_msg.st_PROP.pu8_Data,
pst_Msg->u_msg.st_PROP.u8_DataLen, pst_Msg->u16_Handsets);
break;
case FACILITY_TYPE_DATE_TIME:
APP_FACILITY_INFO_PRINT("Sending DATE AND TIME UPDATE\n");
u8_return = cmbs_dsr_time_Update(g_cmbsappl.pv_CMBSRef, pst_Msg->u_msg.st_DT.u16_RequestId, &pst_Msg->u_msg.st_DT.st_DateTime, pst_Msg->u16_Handsets);
break;
case FACILITY_TYPE_LINE_USE:
APP_FACILITY_INFO_PRINT("Sending LINE USE INDICATION\n");
u8_return = cmbs_dsr_gen_SendLineUseStatusInd(g_cmbsappl.pv_CMBSRef, pst_Msg->u_msg.st_LUI.u16_RequestId, pst_Msg->u_msg.st_LUI.u8_LineId, pst_Msg->u_msg.st_LUI.u32_LineUseStatus, pst_Msg->u16_Handsets);
break;
case FACILITY_TYPE_HANDSET_USE:
APP_FACILITY_INFO_PRINT("Sending HANDSET USE INDICATION\n");
u8_return = cmbs_dsr_gen_SendHSUseStatusInd(g_cmbsappl.pv_CMBSRef, pst_Msg->u_msg.st_HUI.u16_RequestId, pst_Msg->u_msg.st_HUI.u8_LineId, pst_Msg->u16_Handsets);
break;
case FACILITY_TYPE_DIAGNOSTICS:
APP_FACILITY_INFO_PRINT("Sending DIAGNOSTICS INDICATION\n");
u8_return = cmbs_dsr_gen_SendDiagnosticStatusInd(g_cmbsappl.pv_CMBSRef, pst_Msg->u_msg.st_DI.u16_RequestId, pst_Msg->u_msg.st_DI.u8_LineId, pst_Msg->u_msg.st_DI.u8_Type, pst_Msg->u16_Handsets);
break;
case FACILITY_TYPE_SMS:
APP_FACILITY_INFO_PRINT("Sending SMS INDICATION\n");
u8_return = cmbs_dsr_gen_SendSMSNotification(g_cmbsappl.pv_CMBSRef, pst_Msg->u_msg.st_SMS.u16_RequestId, pst_Msg->u_msg.st_SMS.u8_SMSType, pst_Msg->u_msg.st_SMS.u16_NumOfUnreadMsgs, pst_Msg->u_msg.st_SMS.u16_TotalNumOfMsgs, pst_Msg->u16_Handsets);
break;
case FACILITY_PROP_EVENT_NOTIFICATION:
APP_FACILITY_INFO_PRINT("Sending Prop event notification\n");
u8_return = cmbs_dsr_gen_SendPropEventNotification(g_cmbsappl.pv_CMBSRef, pst_Msg->u_msg.st_PropEventNotify.u16_RequestId, pst_Msg->u_msg.st_PropEventNotify.u16_PropEvent, pst_Msg->u_msg.st_PropEventNotify.pu8_Data, pst_Msg->u_msg.st_PropEventNotify.u8_DataLen, pst_Msg->u16_Handsets);
break;
case FACILITY_TYPE_LIST_CHANGED_EX:
APP_FACILITY_INFO_PRINT("Sending LIST CHANGED NOTIF with Details\n");
u8_return = cmbs_dsr_gen_SendListChangedEx(g_cmbsappl.pv_CMBSRef, pst_Msg->u_msg.st_LCN.u16_RequestId, pst_Msg->u16_Handsets,
pst_Msg->u_msg.st_LCN.u8_ListId, pst_Msg->u_msg.st_LCN.u8_ListEntries, pst_Msg->u_msg.st_LCN.u8_LineId, pst_Msg->u_msg.st_LCN.u8_LineSubtype, (PST_IE_GEN_EVENT_DETAILS)&pst_Msg->u_msg.st_LCN.st_Details);
break;
default:
APP_FACILITY_ERROR_PRINT("Unkown facility message type\n");
break;
}
if (u8_return == CMBS_RC_ERROR_NOT_SUPPORTED)
{
// remove message from FIFO
cmbs_util_FifoPop(&app_FacilityFifos[handset]);
}
}
}
}
return CMBS_RC_OK;
}
// ========== app_FacilityMWI ===========
/*!
\brief sending Voice/SMS/Email Message Waiting Indication
\param[in,out] psz_Handsets pointer to parameter string,e.g."1234" or "all"
\return <E_CMBS_RC>
*/
E_CMBS_RC app_FacilityMWI(u16 u16_RequestId, u8 u8_LineId, u16 u16_Messages, u16 u16_HSMask, E_CMBS_MWI_TYPE eType)
{
ST_APP_FACILITY_MSG msg;
APP_FACILITY_INFO_PRINT("app_FacilityMWI\n");
msg.e_type = FACILITY_TYPE_MWI;
msg.u16_Handsets = u16_HSMask;
msg.u_msg.st_MWI.u16_RequestId = u16_RequestId;
msg.u_msg.st_MWI.u8_LineId = u8_LineId;
msg.u_msg.st_MWI.u16_Messages = u16_Messages;
msg.u_msg.st_MWI.eType = eType;
// push to Fifos
app_Facility_PushToFifos(&msg);
// send to target if needed
return app_Facility_SendToTarget(u16_HSMask, NEW_MSG_ADDED);
}
E_CMBS_RC app_FacilityMissedCalls(u16 u16_RequestId, u8 u8_LineId, u16 u16_NewMissedCalls, u16 u16_HSMask, bool bNewMissedCall, u16 u16_TotalMissedCalls)
{
ST_APP_FACILITY_MSG msg;
APP_FACILITY_INFO_PRINT("app_FacilityMissedCalls\n");
msg.e_type = FACILITY_TYPE_MISSED_CALL;
msg.u16_Handsets = u16_HSMask;
msg.u_msg.st_MCN.u16_RequestId = u16_RequestId;
msg.u_msg.st_MCN.u8_LineId = u8_LineId;
msg.u_msg.st_MCN.u16_NewMissedCalls = u16_NewMissedCalls;
msg.u_msg.st_MCN.bNewMissedCall = bNewMissedCall;
msg.u_msg.st_MCN.u16_TotalMissedCalls = u16_TotalMissedCalls;
// push to Fifos
app_Facility_PushToFifos(&msg);
// send to target if needed
return app_Facility_SendToTarget(u16_HSMask, NEW_MSG_ADDED);
}
E_CMBS_RC app_FacilityListChanged(u16 u16_RequestId, u8 u8_ListId, u8 u8_ListEntries, u16 u16_HSMask, u8 u8_LineId, u8 u8_LineSubtype)
{
ST_APP_FACILITY_MSG msg;
APP_FACILITY_INFO_PRINT("app_FacilityListChanged\n");
msg.e_type = FACILITY_TYPE_LIST_CHANGED;
msg.u16_Handsets = u16_HSMask;
msg.u_msg.st_LCN.u16_RequestId = u16_RequestId;
msg.u_msg.st_LCN.u8_ListId = u8_ListId;
msg.u_msg.st_LCN.u8_ListEntries = u8_ListEntries;
msg.u_msg.st_LCN.u8_LineId = u8_LineId;
msg.u_msg.st_LCN.u8_LineSubtype = u8_LineSubtype;
// push to Fifos
app_Facility_PushToFifos(&msg);
// send to target if needed
return app_Facility_SendToTarget(u16_HSMask, NEW_MSG_ADDED);
}
E_CMBS_RC app_FacilityWebContent(u16 u16_RequestId, u8 u8_NumOfWebCont, u16 u16_HSMask)
{
ST_APP_FACILITY_MSG msg;
APP_FACILITY_INFO_PRINT("app_FacilityWebContent\n");
msg.e_type = FACILITY_TYPE_WEB_CONTENT;
msg.u16_Handsets = u16_HSMask;
msg.u_msg.st_WC.u16_RequestId = u16_RequestId;
msg.u_msg.st_WC.u8_NumOfWebCont = u8_NumOfWebCont;
// push to Fifos
app_Facility_PushToFifos(&msg);
// send to target if needed
return app_Facility_SendToTarget(u16_HSMask, NEW_MSG_ADDED);
}
E_CMBS_RC app_FacilityPropEvent(u16 u16_RequestId, u16 u16_Reserved, u8 *pu8_Data, u8 u8_DataLen, u16 u16_HSMask)
{
ST_APP_FACILITY_MSG msg;
APP_FACILITY_INFO_PRINT("app_FacilityPropEvent\n");
msg.e_type = FACILITY_TYPE_PROP_EVENT;
msg.u16_Handsets = u16_HSMask;
msg.u_msg.st_PROP.u16_RequestId = u16_RequestId;
msg.u_msg.st_PROP.u16_Reserved = u16_Reserved;
memcpy(msg.u_msg.st_PROP.pu8_Data, pu8_Data, sizeof(msg.u_msg.st_PROP.pu8_Data));
msg.u_msg.st_PROP.u8_DataLen = u8_DataLen;
// push to Fifos
app_Facility_PushToFifos(&msg);
// send to target if needed
return app_Facility_SendToTarget(u16_HSMask, NEW_MSG_ADDED);
}
E_CMBS_RC app_FacilityDateTime(u16 u16_RequestId, ST_DATE_TIME *pst_DateTime, u16 u16_HSMask)
{
ST_APP_FACILITY_MSG msg;
APP_FACILITY_INFO_PRINT("app_FacilityDateTime\n");
msg.e_type = FACILITY_TYPE_DATE_TIME;
msg.u16_Handsets = u16_HSMask;
msg.u_msg.st_DT.u16_RequestId = u16_RequestId;
memcpy(&msg.u_msg.st_DT.st_DateTime, pst_DateTime, sizeof(msg.u_msg.st_DT.st_DateTime));
// push to Fifos
app_Facility_PushToFifos(&msg);
// send to target if needed
return app_Facility_SendToTarget(u16_HSMask, NEW_MSG_ADDED);
}
E_CMBS_RC app_FacilityPropEventNotification(u16 u16_RequestId, u16 u16_PropEvent, u8 * pu8_Data, u8 u8_DataLen, char * psz_Handsets)
{
ST_APP_FACILITY_MSG msg;
E_CMBS_RC e_rc;
u16 u16_Handsets = app_HandsetMap(psz_Handsets);
msg.e_type = FACILITY_PROP_EVENT_NOTIFICATION;
msg.u16_Handsets = u16_Handsets;
msg.u_msg.st_PropEventNotify.u16_RequestId = u16_RequestId;
msg.u_msg.st_PropEventNotify.u16_PropEvent = u16_PropEvent;
if (u8_DataLen + FACILITY_PROP_EVENT_HEADER_LEN <= MAX_FACILITY_PROP_EVENT_LEN)
{
msg.u_msg.st_PropEventNotify.pu8_Data[0] = (CUSTOMER_DESCRIMINATOR >> 8) & 0xFF; //Discriminator Upper Byte
msg.u_msg.st_PropEventNotify.pu8_Data[1] = CUSTOMER_DESCRIMINATOR & 0xFF; //Discriminator Lower Byte
memcpy(&msg.u_msg.st_PropEventNotify.pu8_Data[2], pu8_Data, u8_DataLen);
msg.u_msg.st_PropEventNotify.u8_DataLen = u8_DataLen;
// push to Fifos
app_Facility_PushToFifos(&msg);
e_rc = app_Facility_SendToTarget(u16_Handsets, NEW_MSG_ADDED);
}
else
{
e_rc = CMBS_RC_ERROR_OUT_OF_MEM;
}
return e_rc;
}
E_CMBS_RC app_FacilityLineUseIndication(u16 u16_RequestId, u8 u8_LineId, u32 u32_LineUseStatus, u16 u16_Hs)
{
ST_APP_FACILITY_MSG msg;
APP_FACILITY_INFO_PRINT("app_FacilityLineUseIndication\n");
msg.e_type = FACILITY_TYPE_LINE_USE;
msg.u16_Handsets = u16_Hs;
msg.u_msg.st_LUI.u16_RequestId = u16_RequestId;
msg.u_msg.st_LUI.u8_LineId = u8_LineId;
msg.u_msg.st_LUI.u32_LineUseStatus = u32_LineUseStatus;
// push to Fifos
app_Facility_PushToFifos(&msg);
// send to target if needed
return app_Facility_SendToTarget(u16_Hs, NEW_MSG_ADDED);
}
E_CMBS_RC app_FacilityHSUseIndication(u16 u16_RequestId, u8 u8_LineId, u16 u16_Hs)
{
ST_APP_FACILITY_MSG msg;
APP_FACILITY_INFO_PRINT("app_FacilityHSUseIndication\n");
msg.e_type = FACILITY_TYPE_HANDSET_USE;
msg.u16_Handsets = u16_Hs;
msg.u_msg.st_HUI.u16_RequestId = u16_RequestId;
msg.u_msg.st_HUI.u8_LineId = u8_LineId;
// push to Fifos
app_Facility_PushToFifos(&msg);
// send to target if needed
return app_Facility_SendToTarget(u16_Hs, NEW_MSG_ADDED);
}
E_CMBS_RC app_FacilityDiagnosticIndication(u16 u16_RequestId, u8 u8_LineId, u8 u8_Type, u16 u16_Hs)
{
ST_APP_FACILITY_MSG msg;
APP_FACILITY_INFO_PRINT("app_FacilityDiagnosticIndication\n");
msg.e_type = FACILITY_TYPE_DIAGNOSTICS;
msg.u16_Handsets = u16_Hs;
msg.u_msg.st_DI.u16_RequestId = u16_RequestId;
msg.u_msg.st_DI.u8_LineId = u8_LineId;
msg.u_msg.st_DI.u8_Type = u8_Type;
// push to Fifos
app_Facility_PushToFifos(&msg);
// send to target if needed
return app_Facility_SendToTarget(u16_Hs, NEW_MSG_ADDED);
}
E_CMBS_RC app_FacilitySMSMessageNotification(u8 u8_SMSType, u16 u16_TotalNumOfMsgs, u16 u16_NumOfUnreadMsgs, u16 u16_HSMask)
{
ST_APP_FACILITY_MSG msg;
APP_FACILITY_INFO_PRINT("app_FacilitySMSMessageNotification\n");
msg.e_type = FACILITY_TYPE_SMS;
msg.u16_Handsets = u16_HSMask;
msg.u_msg.st_SMS.u16_RequestId = 0;
msg.u_msg.st_SMS.u16_NumOfUnreadMsgs = u16_NumOfUnreadMsgs;
msg.u_msg.st_SMS.u16_TotalNumOfMsgs = u16_TotalNumOfMsgs;
msg.u_msg.st_SMS.u8_SMSType = u8_SMSType;
// push to Fifos
app_Facility_PushToFifos(&msg);
// send to target if needed
return app_Facility_SendToTarget(u16_HSMask, NEW_MSG_ADDED);
}
E_CMBS_RC app_FacilityListChangedEx(u16 u16_RequestId, u8 u8_ListId, u8 u8_ListEntries, u16 u16_HSMask, u8 u8_LineId, u8 u8_LineSubtype,
ST_APP_FACILITY_LCN_DETAILS *pst_Details)
{
ST_APP_FACILITY_MSG msg;
APP_FACILITY_INFO_PRINT("app_FacilityListChangedEx\n");
msg.e_type = FACILITY_TYPE_LIST_CHANGED_EX;
msg.u16_Handsets = u16_HSMask;
msg.u_msg.st_LCN.u16_RequestId = u16_RequestId;
msg.u_msg.st_LCN.u8_ListId = u8_ListId;
msg.u_msg.st_LCN.u8_ListEntries = u8_ListEntries;
msg.u_msg.st_LCN.u8_LineId = u8_LineId;
msg.u_msg.st_LCN.u8_LineSubtype = u8_LineSubtype;
memcpy(&msg.u_msg.st_LCN.st_Details, pst_Details, sizeof(ST_APP_FACILITY_LCN_DETAILS));
// push to Fifos
app_Facility_PushToFifos(&msg);
// send to target if needed
return app_Facility_SendToTarget(u16_HSMask, NEW_MSG_ADDED);
}
// ========== app_FacilityEntity ===========
/*!
\brief CMBS entity to handle response information from target side
\param[in] pv_AppRef application reference
\param[in] e_EventID received CMBS event
\param[in] pv_EventData pointer to IE list
\return <int>
*/
int app_FacilityEntity(void *pv_AppRef, E_CMBS_EVENT_ID e_EventID, void *pv_EventData)
{
ST_IE_RESPONSE st_Response;
UNUSED_PARAMETER(pv_AppRef);
UNUSED_PARAMETER(pv_EventData);
APP_FACILITY_INFO_PRINT("app_FacilityEntity e_EventID %u\n",(u32)e_EventID);
st_Response.e_Response = CMBS_RESPONSE_OK;
switch (e_EventID)
{
case CMBS_EV_DSR_GEN_SEND_MWI_RES:
case CMBS_EV_DSR_GEN_SEND_MISSED_CALLS_RES:
case CMBS_EV_DSR_GEN_SEND_LIST_CHANGED_RES:
case CMBS_EV_DSR_GEN_SEND_WEB_CONTENT_RES:
case CMBS_EV_DSR_GEN_SEND_PROP_EVENT_RES:
case CMBS_EV_DSR_TIME_UPDATE_RES:
case CMBS_EV_DSR_GEN_DIAGNOSTIC_STATUS_RES:
case CMBS_EV_DSR_GEN_LINE_USE_STATUS_RES:
case CMBS_EV_DSR_GEN_HS_USE_STATUS_RES:
case CMBS_EV_DSR_GEN_SEND_SMS_MSG_NOTIFICATION_RES:
case CMBS_EV_DSR_GEN_SEND_PROP_EVENT_NOTIFY_RES:
{
// extract handset number
void *pv_IE;
u16 u16_IE;
u16 u16_Handset = 0;
if ( pv_EventData )
{
cmbs_api_ie_GetFirst(pv_EventData, &pv_IE, &u16_IE);
while (pv_IE != NULL)
{
if ( CMBS_IE_HANDSETS == u16_IE )
{
cmbs_api_ie_HandsetsGet(pv_IE, &u16_Handset);
}
if ( CMBS_IE_RESPONSE == u16_IE )
{
cmbs_api_ie_ResponseGet(pv_IE, &st_Response);
}
cmbs_api_ie_GetNext(pv_EventData, &pv_IE, &u16_IE);
}
}
else
{
APP_FACILITY_ERROR_PRINT("null pointer received !\n");
}
if (st_Response.e_Response == CMBS_RESPONSE_NO_LINK_AVL)
{
// There was no free instance for the handset, delay a bit and retry
SleepMs(200);
// send message again, thus don't remove it
}
else
{
// remove acked message from fifo
cmbs_util_FifoPop(&app_FacilityFifos[(app_HsMask2HsNum(u16_Handset)) - 1]);
}
// send next message to target
app_Facility_SendToTarget(u16_Handset, MSG_SEND_RESPONSE);
return TRUE; // event consumed
}
default:
return FALSE; // event not consumed
}
}
// ========== app_FacilityInit ===========
/*!
\brief Init function for the facility module
\return <int>
*/
E_CMBS_RC app_FacilityInit(void)
{
u8 i;
// init Fifos
for (i = 0; i < CMBS_HS_SUBSCRIBED_MAX_NUM; ++i)
{
cmbs_util_FifoInit(&app_FacilityFifos[i], app_FacilityBuffers[i], sizeof(ST_APP_FACILITY_MSG), MAX_FACILITY_MSG_FOR_HS, FifoCriticalSection);
}
return CMBS_RC_OK;
}
u16 app_HsMask2HsNum(u16 u16_HsMask)
{
u8 u8_i;
for (u8_i = 0; u8_i < 16; ++u8_i)
{
if ( u16_HsMask & (1 << u8_i) )
{
return u8_i + 1;
}
}
return 0;
}
void app_FacilityBlockHsMask(u16 u16_HsMask)
{
u16 u16_prev_BlockHsMask = g_u16_BlockHsMask;
// Blocked HS Mask, This is to temporarily stop facility to some handsets.
g_u16_BlockHsMask = u16_HsMask;
if (u16_prev_BlockHsMask != 0)
{
/* trigger facility to previously blocked handsets */
app_Facility_SendToTarget(u16_prev_BlockHsMask, MSG_SEND_RESPONSE);
}
}
/***** [End Of File] *****************************************************************************************************************************/

View File

@@ -0,0 +1,86 @@
/*!
* \file appfacility.h
* \brief
* \Author stein
*
* @(#) %filespec: appfacility.h~6 %
*
*******************************************************************************
* \par History
* \n==== History ============================================================\n
* date name version action \n
* ----------------------------------------------------------------------------\n
*******************************************************************************/
#if !defined( APPFACILITY_H )
#define APPFACILITY_H
#if defined( __cplusplus )
extern "C"
{
#endif
typedef enum
{
APP_FACILITY_CHANGE_EDIT = 0, /*!< List change due to edit/modification */
APP_FACILITY_CHANGE_ADD, /*!< List change due to addition */
APP_FACILITY_CHANGE_DELETE /*!< List change due to deletion */
} E_APP_FACILITY_CHANGE_REASON;
#define APP_FACILITY_MAX_SUB_DETAILS 5
typedef struct
{
u16 u16_Change; //E_CMBS_LIST_CHANGE_REASON
u16 u16_EntryId;
u16 u16_PosIndex;
} ST_APP_FACILITY_LCN_SUB_DETAILS;
typedef struct
{
u8 u8_Count;
u16 u16_OrgHs;
ST_APP_FACILITY_LCN_SUB_DETAILS st_SubDetails[APP_FACILITY_MAX_SUB_DETAILS]; //E_CMBS_LIST_CHANGE_REASON
} ST_APP_FACILITY_LCN_DETAILS;
E_CMBS_RC app_FacilityInit(void);
E_CMBS_RC app_FacilityMWI( u16 u16_RequestId, u8 u8_LineId, u16 u16_Messages, u16 u16_HSMask, E_CMBS_MWI_TYPE eType );
E_CMBS_RC app_FacilityMissedCalls( u16 u16_RequestId, u8 u8_LineId, u16 u16_NewMissedCalls, u16 u16_HSMask, bool bNewMissedCall, u16 u16_TotalMissedCalls );
E_CMBS_RC app_FacilityListChanged( u16 u16_RequestId, u8 u8_ListId, u8 u8_ListEntries, u16 u16_HSMask, u8 u8_LineId, u8 u8_LineSubtype );
E_CMBS_RC app_FacilityWebContent( u16 u16_RequestId, u8 u8_NumOfWebCont, u16 u16_HSMask );
E_CMBS_RC app_FacilityPropEvent( u16 u16_RequestId, u16 u16_Reserved, u8 * pu8_Data, u8 u8_DataLen, u16 u16_HSMask );
E_CMBS_RC app_FacilityDateTime( u16 u16_RequestId, ST_DATE_TIME * pst_DateTime, u16 u16_Hs);
E_CMBS_RC app_FacilityLineUseIndication(u16 u16_RequestId, u8 u8_LineId, u32 u32_LineUseStatus, u16 u16_Hs);
E_CMBS_RC app_FacilityHSUseIndication( u16 u16_RequestId, u8 u8_LineId, u16 u16_Hs);
E_CMBS_RC app_FacilityDiagnosticIndication( u16 u16_RequestId, u8 u8_LineId, u8 u8_Type, u16 u16_Hs);
E_CMBS_RC app_FacilitySMSMessageNotification(u8 u8_NewSMS, u16 u16_TotalNumOfMsgs, u16 u16_NumOfUnreadMsgs, u16 u16_HSMask);
E_CMBS_RC app_FacilityPropEventNotification(u16 u16_RequestId, u16 u16_PropEvent, u8 * pu8_Data, u8 u8_DataLen, char * psz_Handsets);
E_CMBS_RC app_FacilityListChangedEx(u16 u16_RequestId, u8 u8_ListId, u8 u8_ListEntries, u16 u16_HSMask, u8 u8_LineId, u8 u8_LineSubtype,
ST_APP_FACILITY_LCN_DETAILS *pst_Details);
void app_FacilityBlockHsMask(u16 u16_HsMask);
#define MAX_FACILITY_PROP_EVENT_LEN CMBS_PROP_EVENT_LENGTH
#define FACILITY_PROP_EVENT_HEADER_LEN 5
#define FACILITY_DISCRIMINATOR_TYPE 0x81
#define CUSTOMER_DESCRIMINATOR 0x0505
#include "tcx_hostlog.h"
#define APP_FACILITY_INFO_PRINT(format, ...) tcx_WriteLog(FACILITY_MODULE, LOG_LEVEL_INFO, format, ##__VA_ARGS__ )
#define APP_FACILITY_TRACE_PRINT(format, ...) tcx_WriteLog(FACILITY_MODULE, LOG_LEVEL_TRACE, format, ##__VA_ARGS__ )
#define APP_FACILITY_WARNING_PRINT(format, ...) tcx_WriteLog(FACILITY_MODULE, LOG_LEVEL_WARNING, format, ##__VA_ARGS__ )
#define APP_FACILITY_ERROR_PRINT(format, ...) tcx_WriteLog(FACILITY_MODULE, LOG_LEVEL_ERROR, format, ##__VA_ARGS__ )
#define APP_FACILITY_RT_PRINT(format, ...) tcx_WriteLog(FACILITY_MODULE, LOG_LEVEL_REAL_TIME, format, ##__VA_ARGS__ )
#define APP_FACILITY_PRINT_DATA(pu8_Buffer, u16_Length) tcx_WriteLogData(FACILITY_MODULE, LOG_LEVEL_INFO, pu8_Buffer, u16_Length)
#if defined( __cplusplus )
}
#endif
#endif //APPFACILITY_H
//*/

View File

@@ -0,0 +1,197 @@
/*!
* \file appfun.c
* \brief HAN FUN API
* \author ULE BS Team
*
*
*******************************************************************************/
#include "cfr_ie.h"
#include "cmbs_han.h"
#include "cmbs_fun.h"
#include "appfun.h"
#include "appstreambuffer.h"
#include "tcx_hostlog.h"
#define HAN_FUN_APP_INFO_PRINT(format, ...) tcx_WriteLog(FUN_APP, LOG_LEVEL_INFO, format, ##__VA_ARGS__ )
#define HAN_FUN_APP_TRACE_PRINT(format, ...) tcx_WriteLog(FUN_APP, LOG_LEVEL_TRACE, format, ##__VA_ARGS__ )
#define HAN_FUN_APP_WARNING_PRINT(format, ...) tcx_WriteLog(FUN_APP, LOG_LEVEL_WARNING, format, ##__VA_ARGS__ )
#define HAN_FUN_APP_ERROR_PRINT(format, ...) tcx_WriteLog(FUN_APP, LOG_LEVEL_ERROR, format, ##__VA_ARGS__ )
#define HAN_FUN_APP_RT_PRINT(format, ...) tcx_WriteLog(FUN_APP, LOG_LEVEL_REAL_TIME, format, ##__VA_ARGS__ )
#define HAN_FUN_APP_PRINT_DATA(pu8_Buffer, u16_Length) tcx_WriteLogData(FUN_APP, LOG_LEVEL_INFO, pu8_Buffer, u16_Length)
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
// TODO: use serialize and deserialize CMBS methods and remove these hardcoded methods
///////////////////////////////////////////////////////////////////////////////////
u16 pr_hanEndian_SwapBytesU16( u16 u16_Value )
{
return ( ((u16_Value & 0x00FF) << 8) |
((u16_Value & 0xFF00) >> 8) );
}
u32 pr_hanEndian_SwapBytesU32( u32 u32_Value )
{
return ( ( (u32_Value & 0x000000FF) << 24 ) |
( (u32_Value & 0x0000FF00) << 8 ) |
( (u32_Value & 0x00FF0000) >> 8 ) |
( (u32_Value & 0xFF000000) >> 24 ) );
}
u32 pr_hanEndian_HtoN_u32( u32 u32_Value )
{
return pr_hanEndian_SwapBytesU32( u32_Value );
}
u32 pr_hanEndian_NtoH_u32( u32 u32_Value )
{
return pr_hanEndian_SwapBytesU32( u32_Value );
}
u16 pr_hanEndian_HtoN_u16( u16 u16_Value )
{
return pr_hanEndian_SwapBytesU16( u16_Value );
}
u16 pr_hanEndian_NtoH_u16( u16 u16_Value )
{
return pr_hanEndian_SwapBytesU16( u16_Value );
}
///////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////// app_fun_ParseFUNRegistrationMessage /////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void app_fun_ParseFUNRegistrationMessage(IN u8 *p_Msg, OUT PST_FUN_DEVICE_INFO pst_FunInfoEepromStructure)
{
u8 u, i, length;
t_st_streamBuffer st_OtaStream;
u8 u8_Field;
u8 DiscriminatorType;
u8 DeviceUIDSize;
PST_IE_HAN_MSG pstIe_Msg = (PST_IE_HAN_MSG) p_Msg;
app_streamBuffer_CreateWithPayload(&st_OtaStream, pstIe_Msg->pu8_Data, pstIe_Msg->u16_DataLen, pstIe_Msg->u16_DataLen);
// Discriminator Type and Dev UID Type
u8_Field = app_streamBuffer_GetData8(&st_OtaStream);
DiscriminatorType = GET_BITFIELD_VAL( u8_Field, FUN_IF_DEV_MNGT_REG_DISCRIMINATOR_TYPE );
DeviceUIDSize = app_streamBuffer_GetData8(&st_OtaStream);
// Device UID ( variable length ) - we are going to just skip it for now
app_streamBuffer_SkipData8Array(&st_OtaStream, DeviceUIDSize);
// Discriminator Value Optional
if ( DiscriminatorType == FUN_IF_DEV_MNGT_REG_RESP_DISCR_TYPE_PROPRIETARY )
{
// Need to read and store the Descriminator Value ( EMC )
pst_FunInfoEepromStructure->DeviceEMC = pr_hanEndian_NtoH_u16(app_streamBuffer_GetData16(&st_OtaStream));
}
else
{
pst_FunInfoEepromStructure->DeviceEMC = 0;
}
pst_FunInfoEepromStructure->NumOfUnits = app_streamBuffer_GetData8(&st_OtaStream);
if(pst_FunInfoEepromStructure->NumOfUnits > MAX_NUM_OF_UNITS_IN_DEVICE)
{
pst_FunInfoEepromStructure->NumOfUnits = MAX_NUM_OF_UNITS_IN_DEVICE;
}
for (u=0; u < pst_FunInfoEepromStructure->NumOfUnits; u++)
{
//read Unit #u
//if Unit is not supporting optional interfaces, we know it only according to the length=3 (there will be no NumberOfOptionalInterfaces field at all)
length = app_streamBuffer_GetData8(&st_OtaStream);
//read Unit Id
pst_FunInfoEepromStructure->Units[u].UnitId = app_streamBuffer_GetData8(&st_OtaStream);
//read Unit type
pst_FunInfoEepromStructure->Units[u].UnitType = pr_hanEndian_NtoH_u16(app_streamBuffer_GetData16(&st_OtaStream));
if(length > 3 ) //sizeof unitId + sizeof UnitType
{
//read number of optional interfaces
pst_FunInfoEepromStructure->Units[u].NumberOfOptionalInterfaces = app_streamBuffer_GetData8(&st_OtaStream);
if(pst_FunInfoEepromStructure->Units[u].NumberOfOptionalInterfaces > MAX_NUM_OF_OPTIONAL_INTERFACES_IN_UNIT)
{
pst_FunInfoEepromStructure->Units[u].NumberOfOptionalInterfaces = MAX_NUM_OF_OPTIONAL_INTERFACES_IN_UNIT;
}
//read all optional interface
for(i=0; i < pst_FunInfoEepromStructure->Units[u].NumberOfOptionalInterfaces; i++)
{
pst_FunInfoEepromStructure->Units[u].OptionalInterfaces[i] = pr_hanEndian_NtoH_u16(app_streamBuffer_GetData16(&st_OtaStream));
}
}
else
{
pst_FunInfoEepromStructure->Units[u].NumberOfOptionalInterfaces = 0;
}
}
pst_FunInfoEepromStructure->DeviceId = pstIe_Msg->u16_SrcDeviceId;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////// app_fun_BuildFUNRegistrationResponse /////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void app_fun_BuildFUNRegistrationResponse(IN u8 *p_Msg, OUT u8 *p_ResMsg, OUT u8 *p_ResMsgCtl)
{
t_st_streamBuffer st_OtaStream;
u8 RegResponse = 0;
PST_IE_HAN_MSG pstIe_RegMsg = (PST_IE_HAN_MSG) p_Msg;
PST_IE_HAN_MSG pstIe_ResMsg = (PST_IE_HAN_MSG) p_ResMsg;
PST_IE_HAN_MSG_CTL pst_HANResMsgCtl = (PST_IE_HAN_MSG_CTL) p_ResMsgCtl;
// initialize pst_HANResMsgCtl
pst_HANResMsgCtl->ImmediateSend = 0;
pst_HANResMsgCtl->IsLast = 0;
pst_HANResMsgCtl->Reserved = 0;
app_streamBuffer_CreateEmpty(&st_OtaStream, pstIe_ResMsg->pu8_Data, CMBS_HAN_MAX_MSG_LEN);
// fill the network part
pstIe_ResMsg->u16_SrcDeviceId = OTA_BASE_DEVICE_ID;
pstIe_ResMsg->u8_SrcUnitId = OTA_BASE_UNIT_MANAGMENT_UNIT_ID;
pstIe_ResMsg->u16_DstDeviceId = pstIe_RegMsg->u16_SrcDeviceId;
pstIe_ResMsg->u8_DstUnitId = OTA_DST_UNIT_MANAGMENT_UNIT_ID;
pstIe_ResMsg->u8_DstAddressType = OTA_ADDR_TYPE_INDIVIDUAL;
// fill the application part
pstIe_ResMsg->u8_MsgSequence = pstIe_RegMsg->u8_MsgSequence;
pstIe_ResMsg->e_MsgType = OTA_MSG_TYPE_COMMAND_RESPONSE;
pstIe_ResMsg->u8_InterfaceType = OTA_INTERFACE_TYPE_SERVER;
pstIe_ResMsg->u16_InterfaceId = FUN_INTERFACE_DEVICE_MGNT;
pstIe_ResMsg->u8_InterfaceMember = FUN_IF_DEV_MNGT_CMD_REGISTER_DEVICE;
app_streamBuffer_AddData8(&st_OtaStream, RegResponse);
app_streamBuffer_AddData16(&st_OtaStream, pr_hanEndian_HtoN_u16(pstIe_ResMsg->u16_DstDeviceId | (FUN_IF_DEV_MNGT_REG_RESP_DISCR_TYPE_NON_PROPRIETARY << (sizeof(pstIe_ResMsg->u16_DstDeviceId)-1))));
// update length of data
pstIe_ResMsg->u16_DataLen = app_streamBuffer_GetDataSize(&st_OtaStream);
pstIe_ResMsg->st_MsgTransport.u16_Reserved = 0;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*---------[End Of File]---------------------------------------------------------------------------------------------------------------------------*/

View File

@@ -0,0 +1,60 @@
/*!
* \file appfun.h
* \brief HAN FUN API
* \author ULE BS Team
*
*
*
*******************************************************************************/
#if !defined( _APPFUN_H )
#define _APPFUN_H
#include "cmbs_api.h"
////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Methods ////
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ========== app_fun_ParseFUNRegistrationMessage ===========
/*!
\brief
This function parses FUN registration msg received from device stIe_Msg
and stores FUN registration data in pst_FunInfoEepromStructure
void app_fun_ParseFUNRegistrationMessage(IN u8 *stIe_Msg, OUT PST_FUN_DEVICE_INFO pst_FunInfoEepromStructure)
\param[in] stIe_Msg reference pointer to CMBS msg stores FUN Registration msg
\param[out] pst_FunInfoEepromStructure pointer to a struct used to store FUN registration data
\return void
*/
void app_fun_ParseFUNRegistrationMessage(IN u8 *stIe_Msg, OUT PST_FUN_DEVICE_INFO pst_FunInfoEepromStructure);
// ========== app_fun_BuildFUNRegistrationResponse ===========
/*!
\brief
This function builds FUN registration msg response to be sent to adevice p_ResMsg and p_ResMsgCtl
void app_fun_BuildFUNRegistrationResponse(IN u8 *p_Msg, OUT u8 *p_ResMsg, OUT u8 *p_ResMsgCtl)
\param[in] p_Msg reference pointer CMBS msg stores FUN Registration msg
\param[out] p_ResMsg reference pointer to CMBS msg to store FUN Registration msg response
\param[out] p_ResMsgCtl reference pointer to CMBS control msg FUN Registration msg control info
\return void
*/
void app_fun_BuildFUNRegistrationResponse(IN u8 *p_Msg, OUT u8 *p_ResMsg, OUT u8 *p_ResMsgCtl);
#endif // _APPFUN_H
/**********************[End Of File]**********************************************************************************************************/
/*---------[End Of File]---------------------------------------------------------------------------------------------------------------------------*/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,197 @@
/*!
* \file apphan.h
* \brief HAN API
* \author CMBS Team
*
*
*******************************************************************************/
#if !defined( _APPHAN_H )
#define _APPHAN_H
#include "cmbs_han.h"
#include "hanfun_protocol_defs.h"
#include "cmbs_fifo.h"
int app_HANEntity ( void * pv_AppRef, E_CMBS_EVENT_ID e_EventID, void * pv_EventData );
E_CMBS_RC app_DsrHanMngrInit ( ST_HAN_CONFIG * pst_HANConfig );
E_CMBS_RC app_DsrHanMngrStart ( void );
E_CMBS_RC app_DsrHanDeviceReadTable (u16 u16_NumOfEntries, u16 u16_IndexOfFirstEntry, u8 isBrief );
E_CMBS_RC app_DsrHanReadExtendedDeviceTablePhase2 (u16 u16_NumOfEntries, u16 u16_IndexOfFirstEntry);
E_CMBS_RC app_DsrHanDeviceWriteTable (u16 u16_NumOfEntries, u16 u16_IndexOfFirstEntry, ST_HAN_DEVICE_ENTRY * pst_HANDeviceEntriesArray);
E_CMBS_RC app_DsrHanBindReadTable (u16 u16_NumOfEntries, u16 u16_IndexOfFirstEntry );
E_CMBS_RC app_DsrHanBindWriteTable (u16 u16_NumOfEntries, u16 u16_IndexOfFirstEntry, ST_HAN_BIND_ENTRY * pst_HANBindEntriesArray );
E_CMBS_RC app_DsrHanBindAddEntry (PST_HAN_BIND_ENTRY pst_HANBindEntry);
E_CMBS_RC app_DsrHanBindRemoveEntry(PST_HAN_BIND_ENTRY pst_HANBindEntry);
E_CMBS_RC app_DsrHanClearBindTable( void );
E_CMBS_RC app_DsrHanGroupReadTable (u16 u16_NumOfEntries, u16 u16_IndexOfFirstEntry, u16 u16_GroupId);
E_CMBS_RC app_DsrHanGroupReadList (u16 u16_NumOfEntries, u16 u16_IndexOfFirstEntry );
E_CMBS_RC app_DsrHanReadBroadcastCahnnelTable (u16 u16_NumOfEntries, u16 u16_IndexOfFirstEntry);
E_CMBS_RC app_DsrHanGroupWriteTable (u16 u16_NumOfEntries, u16 u16_IndexOfFirstEntry, ST_HAN_GROUP_TABLE_ENTRY * pst_HANGroupEntriesArray );
E_CMBS_RC app_DsrHanGroupCreateGroup ( u8 u8_BroadcastChannelId );
E_CMBS_RC app_DsrHanGroupRemoveGroup ( u16 u16_GroupId );
E_CMBS_RC app_DsrHanGroupAddDeviceToGroup(u16 u16_GroupId, u16 u16_DeviceId, u8 u8_UnitId);
E_CMBS_RC app_DsrHanGroupRemoveDeviceFromGroup(u16 u16_GroupId, u16 u16_DeviceId, u8 u8_UnitId);
E_CMBS_RC app_DsrHanMsgRecvRegister (ST_HAN_MSG_REG_INFO * pst_HANMsgRegInfo);
E_CMBS_RC app_DsrHanMsgRecvUnregister (ST_HAN_MSG_REG_INFO * pst_HANMsgRegInfo);
E_CMBS_RC app_DsrHanMsgSendTxRequest (u16 u16_DeviceId );
E_CMBS_RC app_DsrHanMsgSendTxEnd (u16 u16_DeviceId );
E_CMBS_RC app_DsrHanMsgSend (u16 u16_RequestId, u16 u16_DestDeviceId, ST_IE_HAN_MSG_CTL* pst_HANMsgCtl ,ST_IE_HAN_MSG * pst_HANMsg);
E_CMBS_RC app_DsrHanRawMsgSend (u16 u16_RequestId, u16 u16_DestDeviceId, ST_IE_HAN_MSG_CTL* pst_HANMsgCtl ,ST_IE_DATA * pst_HANRawMsg);
E_CMBS_RC app_DsrHanDeleteDevice (u16 u16_DeviceId , bool b_BlackList);
E_CMBS_RC app_DsrHanSendBaseUpdatedNotification ( u16 u16_DeviceId );
E_CMBS_RC app_DsrHanGetFunProtocolInfo ();
E_CMBS_RC app_DsrHanGetDeviceConnectionStatus ( u16 u16_DeviceId );
E_CMBS_RC app_DsrHanReadSingleDeviceRegistrationInformation(u16 u16_DeviceId);
E_CMBS_RC app_DsrHanReadSingleDeviceRegistrationInformationPhase2(u16 u16_DeviceId);
E_CMBS_RC app_DsrHan_HanSetLogLevel(u8 u8_LogLevel);
E_CMBS_RC app_DsrHan_HanGetLogLevel(void);
E_CMBS_RC app_DsrHanLoggerEnable(bool b_enable);
E_CMBS_RC app_DsrHanCpLoggerEnable(bool b_enable);
E_CMBS_RC app_DsrHanNotifyOnVoiceCall(u16 u16_DeviceId);
E_CMBS_RC app_DsrHanGetMaxNumOfDevices(void);
E_CMBS_RC app_DsrHanReadBlackListedDeviceTable (u16 u16_NumOfEntries, u16 u16_IndexOfFirstEntry);
E_CMBS_RC app_DsrHanMarkCcmKeyAsUsed( u16 u16_DeviceNumber , u8 u8_CCMKeyUsed);
E_CMBS_RC app_DsrHanSetTxMicCorruptNum(u16 u16_DeviceNumber);
E_CMBS_RC app_DsrHanSetTxSeqNum(u16 u16_DeviceNumber, u16 u16_TxSequenceNumber );
E_CMBS_RC app_DsrHanGetTxSeqNum(u16 u16_DeviceNumber);
E_CMBS_RC app_DsrHanGetRxSeqNum(u16 u16_DeviceNumber);
E_CMBS_RC app_DsrHanSetTxAckDropNum(u16 u16_TxAckDropNumber);
E_CMBS_RC app_DsrHanSetPvcState(u16 u16_DeviceNumber, u8 u8_PVCState );
E_CMBS_RC app_DsrHanSetRxGain(u8 u8_RxGainVal );
E_CMBS_RC app_DsrHanGetRxGain(void );
E_CMBS_RC app_DsrHanSendPvcResetReq( u16 u16_DeviceNumber );
E_CMBS_RC app_DsrHanGetPvcResetReqState( u16 u16_DeviceNumber );
E_CMBS_RC app_DsrHanReadFullDeviceRegistrationInfo(u16 u16_DeviceId);
E_CMBS_RC app_DsrHanWriteFullDeviceRegistrationInfo(u16 u16_DeviceId, ST_HAN_FULL_DEVICE_REGISTRATION_INFO *pst_DeviceRegistrationInfo);
E_CMBS_RC app_DsrHanTBR6SetPM(u8 u8_Carrier , u32 u32_Period );
E_CMBS_RC app_DsrHanTBR6SetGUCI(u8 * pIPUI );
E_CMBS_RC app_DsrHanTBR6ResetStatistics(void );
E_CMBS_RC app_DsrHanModificationULEPagingInterval (u16 u16_DeviceId, u32 u32_ULEPagingIntervalMs );
E_CMBS_RC app_DsrHanNodeSetupAttemptsEnable (bool b_enable);
E_CMBS_RC app_DsrHanGetNumOfRegDevices(void);
E_CMBS_RC app_DsrHanStartVbs (u16 u16_GroupId);
E_CMBS_RC app_DsrHanStopVbs (u16 u16_GroupId);
E_CMBS_RC app_DsrHanReadBroadcastChannelType (u8 u8_BroadcastChannelId);
E_CMBS_RC app_DsrHanReadDeviceVbsCapabilities (u16 u16_DeviceId);
void SetWaitForReady(u16 u16_deviceId, bool Mode);
bool GetWaitForReady(u16 u16_deviceId);
void SetDuringDeleteReq(bool status);
bool SetIfNotAlreadyDuringDeleteReq(void);
void SetReleaseLink(u16 u16_deviceId, bool ReleaseLinkMode);
bool GetReleaseLink(u16 u16_deviceId);
PST_CMBS_FIFO Get_UleMsgFifo(u16 u16_deviceId);
PST_CMBS_FIFO Get_UleRawMsgFifo(u16 u16_deviceId);
void app_HanPushPendingDeviceToDelete(u16 u16_deviceId, bool b_BlackList);
u16 app_HanPopPendingDeviceToDelete();
u8 app_HanDbGetFunMsgQSizeForDevice();
void app_DsrHanVoiceCallReq (u16 u16_DstDeviceId, u8 u8_DstUnitId, PST_HAN_VOICE_CALL_REQ_PARAMS Pst_CallReqParams);
void app_HanOnFunMsgReceived(void *pv_EventData, ST_IE_HAN_MSG * pstIe_Msg );
void app_HanOnRawMsgReceived(void *pv_EventData, ST_IE_DATA * pstIe_RawMsg );
void app_HanRegularStart( u8 RegisterForHanMessages );
void app_HanPrintMessageFields(ST_IE_HAN_MSG* pMsg);
void app_HanPrintRawMessageFields(ST_IE_DATA* pMsg, u16 u16_DeviceId);
u8 app_HAN_GetHANConfiguration( void );
void app_HAN_SetHANConfiguration(u8 u8_HANServiceConfig);
u8 app_HAN_GetHANConfiguration( void );
void app_HAN_SetHANConfiguration(u8 u8_HANServiceConfig);
void app_HANRestoreSequenceNumbers (void);
void app_HanOnSuotaOverFunMsgReceived(ST_IE_HAN_MSG * stIe_Msg );
void app_HanSendSUOTAOverFunGetChunkRes(u8 deviceId, u8 AppRef, u8 * u8_Buffer, u16 u16_BuffLen );
void appHanDbHandleDevDeleteOnTargetUp();
void app_HanDbInitialize();
#ifdef WIN32
DWORD app_tempThread(LPVOID lpThreadParameter);
#elif __linux__
void* app_tempThread(void *ptr);
#endif
#define MAX_ULE_DEVICES_HOST 1001 // Maximal number of ULE that host supports + 1 (to include also device 0 that is not used today)
#define ALL_ULE_DEVICES_HOST 0xFFFF // All devices as a group
#define NO_ULE_DEVICE_HOST 0xFFFE // for internal use only
// Test Mode interface
#define HAN_IFACE_TESTMODE 0x7F01
// server attributes
#define HAN_IFACE_TESTMODE_ATTR_BULK_SIZE 1
#define HAN_IFACE_TESTMODE_ATTR_BULK_INTERVAL 2
#define HAN_IFACE_TESTMODE_ATTR_PACKET_INTERVAL 3
// commands client to server
#define HAN_IFACE_TESTMODE_CMD_ENABLE 1
#define HAN_IFACE_TESTMODE_CMD_TXTDD_START 2
// needed for payload
#define HAN_IFACE_TESTMODE_CMD_ENABLE_VALUE_DISABLE 0// payload of one Byte for the command (0 Disable , 1 Enable)
#define HAN_IFACE_TESTMODE_CMD_ENABLE_VALUE_ENABLE 1
// MEMORY Access interface
#define HAN_IFACE_MEMORY_ACCESS 0x7F04
// commands client to server
#define HAN_IFACE_EEPROM_ACCESS_CMD_GET 1
#define HAN_IFACE_EEPROM_ACCESS_CMD_SET 2
// Interface direction
#define HAN_IFACE_DIRECTION_SERVER 1
#define HAN_IFACE_DIRECTION_CLIENT 0
#define MEMORY_ACCESS_CMND_PAYLOAD_HEADER_SIZE 7
#define MEMORY_ACCESS_CMND_PAYLOAD_MAX_SIZE 500
#define HAN_TEST_DIALOG 3
typedef struct
{
ST_IE_HAN_MSG st_HANmsg;
u8 paylod[CMBS_HAN_MAX_MSG_LEN*2];
} ST_IE_FULL_HAN_MSG , * PST_IE_FULL_HAN_MSG;
typedef struct
{
bool b_Response;
u16 u16_deviceID;
u16 u16_status;
}ST_CMBS_IE_RES, *PST_CMBS_IE_RES;
typedef struct // Msg Struct to be saved in message Queue
{
ST_IE_HAN_MSG_CTL st_HANMsgCtl;
ST_IE_HAN_MSG st_HANMsg;
u8 Payload[CMBS_HAN_MAX_MSG_DATA_LEN];
}ST_FUN_MSG, *PST_FUN_MSG;
typedef struct // Raw Msg Struct to be saved in message Queue
{
ST_IE_HAN_MSG_CTL st_HANMsgCtl;
ST_IE_DATA st_RawMsg;
u16 u16_DeviceId;
u8 Payload[CMBS_HAN_MAX_MSG_DATA_LEN];
}ST_RAW_MSG, *PST_RAW_MSG;
#endif // _APPHAN_H
/**********************[End Of File]**********************************************************************************************************/

View File

@@ -0,0 +1,254 @@
/*!
* \file apphan.c
* \brief HAN API
* \author CMBS Team
*
*
*******************************************************************************/
#include <string.h>
#include <stdio.h>
#include "apphanDb.h"
#include "apphan.h"
#include "cfr_mssg.h"
#include "appcmbs.h"
#include "cmbs_fifo.h"
#define FUN_MSG_FIFO_SIZE 20 // max messages per HAN device
#define RAW_MSG_FIFO_SIZE 20 // max raw messages per HAN device
void han_applUleMsgFiFoInitialize();
void han_applRawMsgFiFoInitialize();
////////////////////////////////////////////////////
// Message Queue per ULE device -- definitions
static ST_FUN_MSG g_CMBS_UleMsgBuffer[MAX_ULE_DEVICES_HOST][FUN_MSG_FIFO_SIZE];
static ST_RAW_MSG g_CMBS_UleRawMsgBuffer[MAX_ULE_DEVICES_HOST][RAW_MSG_FIFO_SIZE];
static ST_CMBS_FIFO g_UleMsgFifo[MAX_ULE_DEVICES_HOST];
static ST_CMBS_FIFO g_UleRawMsgFifo[MAX_ULE_DEVICES_HOST];
static bool WaitForReady[MAX_ULE_DEVICES_HOST]; // TxRequest was sent, we ae waiting for TxReady indication
static bool ReleaseLink[MAX_ULE_DEVICES_HOST]; // Dynamically updated by application: If to send TxEnd to device when its fifo is empty, to save link
// Consecutive Delete requests should be serialized.
static st_DeleteRequestQueue PendingDeleteReqests[MAX_ULE_DEVICES_HOST+1]; // last entry is for Delete ALL pending request
static bool DuringDeleteReq=FALSE;
static CFR_CMBS_CRITICALSECTION HanServerCriticalSection;
//////////////////////////////////////////////////
ST_CMBS_FIFO* app_HanDbGetUleMsgFifo()
{
return g_UleMsgFifo;
}
bool app_HanDbPrintFifoStatistic(u16 u16_DeviceID)
{
//print only devices that used fifo
if(g_UleMsgFifo[u16_DeviceID].s_fifo_statistics.u32_MaxInUse > 0)
{
printf("\n\n==== FIFO STATISTICS FOR DEVICE: %d ====\n",u16_DeviceID);
cmbs_util_FifoPrintStatistics(&g_UleMsgFifo[u16_DeviceID]);
return TRUE;
}
return FALSE;
}
void app_HanDbInitialize()
{
han_applUleMsgFiFoInitialize();
han_applRawMsgFiFoInitialize();
CFR_CMBS_INIT_CRITICALSECTION(HanServerCriticalSection); // init of this CS is NOT conditioned by HanServer flag
SetDuringDeleteReq(FALSE);
}
void han_applUleMsgFiFoInitialize ()
{
u32 u32_Index;
for ( u32_Index = 0; u32_Index < MAX_ULE_DEVICES_HOST; ++u32_Index )
{
cmbs_util_FifoInit( &g_UleMsgFifo[u32_Index],
g_CMBS_UleMsgBuffer[u32_Index],
(u16)sizeof(ST_FUN_MSG),
FUN_MSG_FIFO_SIZE,
HanServerCriticalSection); // use same critical section for all devices
WaitForReady[u32_Index] = FALSE;
}
}
///////////////////////////////////////////////////////////////
void han_applRawMsgFiFoInitialize ()
{
u32 u32_Index;
for ( u32_Index = 0; u32_Index < MAX_ULE_DEVICES_HOST; ++u32_Index )
{
cmbs_util_FifoInit( &g_UleRawMsgFifo[u32_Index],
g_CMBS_UleRawMsgBuffer[u32_Index],
(u16)sizeof(ST_RAW_MSG),
RAW_MSG_FIFO_SIZE,
HanServerCriticalSection); // use same critical section for all devices
WaitForReady[u32_Index] = FALSE;
}
}
///////////////////////////////////////////////////////////////
PST_CMBS_FIFO Get_UleMsgFifo(u16 u16_deviceId)
{
return &g_UleMsgFifo[u16_deviceId];
}
///////////////////////////////////////////////////////////////
PST_CMBS_FIFO Get_UleRawMsgFifo(u16 u16_deviceId)
{
return &g_UleRawMsgFifo[u16_deviceId];
}
///////////////////////////////////////////////////////////////
void SetReleaseLink(u16 u16_deviceId, bool ReleaseLinkMode)
{
CFR_CMBS_ENTER_CRITICALSECTION(HanServerCriticalSection);
ReleaseLink[u16_deviceId] = ReleaseLinkMode;
CFR_CMBS_LEAVE_CRITICALSECTION(HanServerCriticalSection);
}
bool GetReleaseLink(u16 u16_deviceId)
{
bool ret;
CFR_CMBS_ENTER_CRITICALSECTION(HanServerCriticalSection);
ret = ReleaseLink[u16_deviceId];
CFR_CMBS_LEAVE_CRITICALSECTION(HanServerCriticalSection);
return ret;
}
///////////////////////////////////////////////////////////////
void SetWaitForReady(u16 u16_deviceId, bool Mode)
{
CFR_CMBS_ENTER_CRITICALSECTION(HanServerCriticalSection);
WaitForReady[u16_deviceId] = Mode;
CFR_CMBS_LEAVE_CRITICALSECTION(HanServerCriticalSection);
}
bool GetWaitForReady(u16 u16_deviceId)
{
bool ret;
CFR_CMBS_ENTER_CRITICALSECTION(HanServerCriticalSection);
ret = WaitForReady[u16_deviceId];
CFR_CMBS_LEAVE_CRITICALSECTION(HanServerCriticalSection);
return ret;
}
///////////////////////////////////////////////////////////////
void SetDuringDeleteReq(bool status)
{
CFR_CMBS_ENTER_CRITICALSECTION(HanServerCriticalSection);
DuringDeleteReq = status;
CFR_CMBS_LEAVE_CRITICALSECTION(HanServerCriticalSection);
}
// This function protects the Delete Request:
// Set only if not already during previous request
// return TRUE iff request was set now
bool SetIfNotAlreadyDuringDeleteReq(void)
{
bool ret = FALSE;
CFR_CMBS_ENTER_CRITICALSECTION(HanServerCriticalSection);
if (!DuringDeleteReq)
{
DuringDeleteReq=TRUE;
ret = TRUE;
}
CFR_CMBS_LEAVE_CRITICALSECTION(HanServerCriticalSection);
return ret;
}
// return u16_deviceId, which may be also ALL_ULE_DEVICES_HOST
u16 app_HanPopPendingDeviceToDelete()
{
int i;
u16 u16_deviceId = NO_ULE_DEVICE_HOST;
CFR_CMBS_ENTER_CRITICALSECTION(HanServerCriticalSection);
for (i = 0; i <= MAX_ULE_DEVICES_HOST; i++) //
{
if (PendingDeleteReqests[i].b_PendingRequest)
{
PendingDeleteReqests[i].b_PendingRequest = FALSE;
if (i == MAX_ULE_DEVICES_HOST)
{
u16_deviceId = ALL_ULE_DEVICES_HOST;
}
else
{
u16_deviceId = i;
if (PendingDeleteReqests[i].b_BlackListDeleteRequest)
{
PendingDeleteReqests[i].b_BlackListDeleteRequest = FALSE;
u16_deviceId |= 0x8000;
}
}
// anyhow break
break;
}
}
CFR_CMBS_LEAVE_CRITICALSECTION(HanServerCriticalSection);
return u16_deviceId;
}
// input u16_deviceId may be ALL_ULE_DEVICES_HOST
void app_HanPushPendingDeviceToDelete(u16 u16_deviceId, bool b_BlackList)
{
CFR_CMBS_ENTER_CRITICALSECTION(HanServerCriticalSection);
if (u16_deviceId == ALL_ULE_DEVICES_HOST)
{
PendingDeleteReqests[MAX_ULE_DEVICES_HOST].b_PendingRequest = TRUE;
}
else
{
PendingDeleteReqests[u16_deviceId].b_PendingRequest= TRUE;
PendingDeleteReqests[u16_deviceId].b_BlackListDeleteRequest = b_BlackList ? TRUE : FALSE;
}
CFR_CMBS_LEAVE_CRITICALSECTION(HanServerCriticalSection);
}
u8 app_HanDbGetFunMsgQSizeForDevice()
{
return FUN_MSG_FIFO_SIZE;
}
void appHanDbHandleDevDeleteOnTargetUp()
{
PendingDeleteReqests[MAX_ULE_DEVICES_HOST].b_BlackListDeleteRequest = FALSE;
PendingDeleteReqests[MAX_ULE_DEVICES_HOST].b_PendingRequest = FALSE;
DuringDeleteReq = FALSE;
}

View File

@@ -0,0 +1,25 @@
/*!
* \file appHanDb.h
* \brief Fifo message queue for CMBS host and CMBS target
* \autor HAN Team
*
*******************************************************************
*/
#if !defined( _APPHANDB_H )
#define _APPHANDB_H
#include "cmbs_fifo.h"
ST_CMBS_FIFO* app_HanDbGetUleMsgFifo();
bool app_HanDbPrintFifoStatistic(u16 u16_DeviceID);
typedef struct st_DeleteRequestQueue
{
bool b_PendingRequest;
bool b_BlackListDeleteRequest;
}st_DeleteRequestQueue, *pst_DeleteRequestQueue;
#endif // _APPHANDB_H

View File

@@ -0,0 +1,227 @@
/*!
* \file apphanvoicecallroutingtable.c
* \brief
* \author Moria Aharon
*
* @(#) apphanvoicecallroutingtable.c~1
*
*******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "apphanvoicecallroutingtable.h"
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
#define INVALID_ENTITY_ID 0
#define ANY_ENTITY_ID (u16)-1
// VoiceCall Routing Table DB
static st_apphan_VoiceCallRoutingTableRecord g_st_apphan_VoiceCallRoutingTable[VOICE_CALL_ROUTING_TABLE_SIZE];
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
bool p_VoiceCallRoutingTable_AddRecordToTable(st_apphan_VoiceCallRoutingTableRecord * pst_apphan_VoiceCallRoutingTableRecord)
{
u16 u16_Index;
if (!p_VoiceCallRoutingTable_IsRecordValid(pst_apphan_VoiceCallRoutingTableRecord))
{
return FALSE;
}
for (u16_Index = 0; u16_Index < VOICE_CALL_ROUTING_TABLE_SIZE; u16_Index++)
{
// search for the first empty record
if (g_st_apphan_VoiceCallRoutingTable[u16_Index].u16_SrcId == INVALID_ENTITY_ID)
{
g_st_apphan_VoiceCallRoutingTable[u16_Index].u8_DstType = pst_apphan_VoiceCallRoutingTableRecord->u8_DstType;
g_st_apphan_VoiceCallRoutingTable[u16_Index].u16_DstId = pst_apphan_VoiceCallRoutingTableRecord->u16_DstId;
g_st_apphan_VoiceCallRoutingTable[u16_Index].u8_DstUnitId = pst_apphan_VoiceCallRoutingTableRecord->u8_DstUnitId;
g_st_apphan_VoiceCallRoutingTable[u16_Index].u8_SrcType = pst_apphan_VoiceCallRoutingTableRecord->u8_SrcType;
g_st_apphan_VoiceCallRoutingTable[u16_Index].u16_SrcId = pst_apphan_VoiceCallRoutingTableRecord->u16_SrcId;
g_st_apphan_VoiceCallRoutingTable[u16_Index].u8_SrcUnitId = pst_apphan_VoiceCallRoutingTableRecord->u8_SrcUnitId;
if (pst_apphan_VoiceCallRoutingTableRecord->pu8_DstDialStr[0] != 0)
strcpy((char *)g_st_apphan_VoiceCallRoutingTable[u16_Index].pu8_DstDialStr, (const char *)pst_apphan_VoiceCallRoutingTableRecord->pu8_DstDialStr);
return TRUE;
}
}
return FALSE;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
bool p_VoiceCallRoutingTable_RemoveRecordFromTable(st_apphan_VoiceCallRoutingTableRecord * pst_apphan_VoiceCallRoutingTableRecord)
{
u16 u16_Index;
for (u16_Index=0; u16_Index<VOICE_CALL_ROUTING_TABLE_SIZE; u16_Index++)
{
if (g_st_apphan_VoiceCallRoutingTable[u16_Index].u8_DstType == pst_apphan_VoiceCallRoutingTableRecord->u8_DstType &&
g_st_apphan_VoiceCallRoutingTable[u16_Index].u16_DstId == pst_apphan_VoiceCallRoutingTableRecord->u16_DstId &&
g_st_apphan_VoiceCallRoutingTable[u16_Index].u8_DstUnitId == pst_apphan_VoiceCallRoutingTableRecord->u8_DstUnitId &&
g_st_apphan_VoiceCallRoutingTable[u16_Index].u8_SrcType == pst_apphan_VoiceCallRoutingTableRecord->u8_SrcType &&
g_st_apphan_VoiceCallRoutingTable[u16_Index].u16_SrcId == pst_apphan_VoiceCallRoutingTableRecord->u16_SrcId &&
g_st_apphan_VoiceCallRoutingTable[u16_Index].u8_SrcUnitId == pst_apphan_VoiceCallRoutingTableRecord->u8_SrcUnitId &&
!strcmp((char *)g_st_apphan_VoiceCallRoutingTable[u16_Index].pu8_DstDialStr, (const char *)pst_apphan_VoiceCallRoutingTableRecord->pu8_DstDialStr))
{
memset((void*) &g_st_apphan_VoiceCallRoutingTable[u16_Index], 0, sizeof(st_apphan_VoiceCallRoutingTableRecord));
return TRUE;
}
}
return FALSE;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
bool p_VoiceCallRoutingTable_IsRecordValid (st_apphan_VoiceCallRoutingTableRecord * pst_apphan_VoiceCallRoutingTableRecord)
{
if (pst_apphan_VoiceCallRoutingTableRecord->u8_SrcType >= ENTITY_TYPE_MAX ||
pst_apphan_VoiceCallRoutingTableRecord->u8_DstType >= ENTITY_TYPE_MAX ||
pst_apphan_VoiceCallRoutingTableRecord->u16_SrcId == INVALID_ENTITY_ID ||
pst_apphan_VoiceCallRoutingTableRecord->u16_DstId == INVALID_ENTITY_ID )
{
return FALSE;
}
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
u16 p_VoiceCallRoutingTable_CountTableEntries(void)
{
u16 u16_Index, u16_EntryCount = 0;
for (u16_Index=0; u16_Index<VOICE_CALL_ROUTING_TABLE_SIZE; u16_Index++)
{
if (g_st_apphan_VoiceCallRoutingTable[u16_Index].u16_SrcId != INVALID_ENTITY_ID)
{
u16_EntryCount++;
}
}
return u16_EntryCount;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
void p_VoiceCallRoutingTable_PrintTable(void)
{
u16 u16_Index;
printf("\n=============================\n");
printf(" VoiceCall Routing Table\n");
printf("=============================\n\n");
for (u16_Index=0; u16_Index<VOICE_CALL_ROUTING_TABLE_SIZE; u16_Index++)
{
if (g_st_apphan_VoiceCallRoutingTable[u16_Index].u16_SrcId != INVALID_ENTITY_ID)
{
printf("Src Type: %s\n", g_st_apphan_VoiceCallRoutingTable[u16_Index].u8_SrcType == DEVICE_ENTITY ? "Device" : "HS");
printf("Src ID: %d\n", g_st_apphan_VoiceCallRoutingTable[u16_Index].u16_SrcId);
if(g_st_apphan_VoiceCallRoutingTable[u16_Index].u8_SrcType == DEVICE_ENTITY)
{
printf("Src Unit ID: %d\n", g_st_apphan_VoiceCallRoutingTable[u16_Index].u8_SrcUnitId);
}
printf("Dst Type: %s\n", g_st_apphan_VoiceCallRoutingTable[u16_Index].u8_DstType==DEVICE_ENTITY ? "Device" : "HS");
printf("Dst ID: %d\n", g_st_apphan_VoiceCallRoutingTable[u16_Index].u16_DstId);
if(g_st_apphan_VoiceCallRoutingTable[u16_Index].u8_DstType == DEVICE_ENTITY)
{
printf("Dst Unit ID: %d\n", g_st_apphan_VoiceCallRoutingTable[u16_Index].u8_DstUnitId);
}
if (g_st_apphan_VoiceCallRoutingTable[u16_Index].pu8_DstDialStr[0])
{
printf("Dst Dial Str: %s\n", g_st_apphan_VoiceCallRoutingTable[u16_Index].pu8_DstDialStr);
}
printf("------------------------------\n");
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
void p_VoiceCallRoutingTable_ClearTable(void)
{
memset( (void *) &g_st_apphan_VoiceCallRoutingTable[0], 0, sizeof(g_st_apphan_VoiceCallRoutingTable));
}
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
bool p_VoiceCallRoutingTable_FindMatchForHS(u16 u16_HsNum, const char *pu8_DialStr, st_apphan_VoiceCallRoutingTableRecord *pst_VoiceCallRoutingTableRecord)
{
u16 u16_Index;
for (u16_Index=0; u16_Index<VOICE_CALL_ROUTING_TABLE_SIZE; u16_Index++)
{
// HS entry
if (g_st_apphan_VoiceCallRoutingTable[u16_Index].u8_SrcType == HS_ENTITY &&
// HS number
(g_st_apphan_VoiceCallRoutingTable[u16_Index].u16_SrcId == ANY_ENTITY_ID || g_st_apphan_VoiceCallRoutingTable[u16_Index].u16_SrcId == u16_HsNum) &&
// check if dest dial string is the same
((g_st_apphan_VoiceCallRoutingTable[u16_Index].pu8_DstDialStr[0] == 0) ||
(pu8_DialStr && !strcmp(pu8_DialStr, (const char *)g_st_apphan_VoiceCallRoutingTable[u16_Index].pu8_DstDialStr))))
{
memcpy((void *) pst_VoiceCallRoutingTableRecord, (void *) &g_st_apphan_VoiceCallRoutingTable[u16_Index], sizeof(st_apphan_VoiceCallRoutingTableRecord));
return TRUE;
}
}
return FALSE;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
bool p_VoiceCallRoutingTable_FindMatchForDevice(u16 u16_DeviceId, u8 u8_UnitId, const char *pu8_DialStr, st_apphan_VoiceCallRoutingTableRecord *pst_VoiceCallRoutingTableRecord)
{
u16 u16_Index;
for (u16_Index=0; u16_Index<VOICE_CALL_ROUTING_TABLE_SIZE; u16_Index++)
{
// Device entry
if (g_st_apphan_VoiceCallRoutingTable[u16_Index].u8_SrcType == DEVICE_ENTITY &&
// device ID
(g_st_apphan_VoiceCallRoutingTable[u16_Index].u16_SrcId == ANY_ENTITY_ID || g_st_apphan_VoiceCallRoutingTable[u16_Index].u16_SrcId == u16_DeviceId) &&
// Unit ID
(g_st_apphan_VoiceCallRoutingTable[u16_Index].u8_SrcUnitId == (u8)ANY_ENTITY_ID || g_st_apphan_VoiceCallRoutingTable[u16_Index].u8_SrcUnitId == u8_UnitId) &&
// check if dest dial string is the same or missinig on both sides
((g_st_apphan_VoiceCallRoutingTable[u16_Index].pu8_DstDialStr[0] == 0) ||
(pu8_DialStr && !strcmp(pu8_DialStr, (const char *)g_st_apphan_VoiceCallRoutingTable[u16_Index].pu8_DstDialStr))))
{
memcpy((void *) pst_VoiceCallRoutingTableRecord, (void *) &g_st_apphan_VoiceCallRoutingTable[u16_Index], sizeof(st_apphan_VoiceCallRoutingTableRecord));
return TRUE;
}
}
return FALSE;
}
//--------[End of file]---------------------------------------------------------------------------------------------------------------------------------

View File

@@ -0,0 +1,59 @@
/*!
* \file apphanvoicecallroutingtable.h
* \brief
* \author Moria Aharon
*
* @(#) apphanvoicecallroutingtable.h~1
*
*******************************************************************************/
#if !defined( _APPHANVOICECALLROUTINGTABLE_H )
#define _APPHANVOICECALLROUTINGTABLE_H
#include "cmbs_api.h"
#define DIAL_STR_LEN 16
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
typedef struct
{
u8 u8_SrcType;
u16 u16_SrcId;
u8 u8_SrcUnitId;
u8 u8_DstType;
u16 u16_DstId;
u8 u8_DstUnitId;
u8 pu8_DstDialStr[DIAL_STR_LEN];
} st_apphan_VoiceCallRoutingTableRecord;
typedef enum
{
HS_ENTITY = 0,
DEVICE_ENTITY,
ENTITY_TYPE_MAX,
} t_en_VoiceCallRoutingTable_EntityType;
// VoiceCall Routing Table Record size
#define VOICE_CALL_ROUTING_TABLE_SIZE 20
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
bool p_VoiceCallRoutingTable_AddRecordToTable(st_apphan_VoiceCallRoutingTableRecord * pst_apphan_VoiceCallRoutingTableRecord);
bool p_VoiceCallRoutingTable_RemoveRecordFromTable(st_apphan_VoiceCallRoutingTableRecord * pst_apphan_VoiceCallRoutingTableRecord);
bool p_VoiceCallRoutingTable_IsRecordValid (st_apphan_VoiceCallRoutingTableRecord * pst_apphan_VoiceCallRoutingTableRecord);
u16 p_VoiceCallRoutingTable_CountTableEntries(void);
void p_VoiceCallRoutingTable_PrintTable(void);
void p_VoiceCallRoutingTable_ClearTable(void);
bool p_VoiceCallRoutingTable_FindMatchForHS(u16 u16_HsNum, const char *pu8_DialStr, st_apphan_VoiceCallRoutingTableRecord *pst_VoiceCallRoutingTableRecord);
bool p_VoiceCallRoutingTable_FindMatchForDevice(u16 u16_DeviceId, u8 u8_UnitId, const char *pu8_DialStr, st_apphan_VoiceCallRoutingTableRecord *pst_VoiceCallRoutingTableRecord);
#endif // _APPHANAUDIOROUTINGTABLE_H

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,31 @@
/*!
* \file applistacc.h
* \brief
* \Author stein
*
* @(#) %filespec: applistacc.h~DMZD53#3 %
*
*******************************************************************************
* \par History
* \n==== History ============================================================\n
* date name version action \n
* ----------------------------------------------------------------------------\n
*******************************************************************************/
#if !defined( APPLISTACC_H )
#define APPLISTACC_H
#if defined( __cplusplus )
extern "C"
{
#endif
void app_LaInitialize( void );
#if defined( __cplusplus )
}
#endif
#endif //APPCATIQ_H
//*/

View File

@@ -0,0 +1,173 @@
/*!
* \file applog.c
* \brief handles DECT logger functionality
* \Author podolskyi
*
* @(#) %filespec: applog.c~3 %
*
*******************************************************************************
* \par History
* \n==== History ============================================================\n
* date name version action \n
* ----------------------------------------------------------------------------\n
*
*******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cmbs_api.h"
#include "cfr_ie.h"
#include "cfr_mssg.h"
#include "cfr_debug.h"
#include "appcmbs.h"
#include "appmsgparser.h"
FILE* g_pDectLogFile=NULL;
//////////////////////////////////////////////////////////////////////////
/// externs
//////////////////////////////////////////////////////////////////////////
extern void app_DectLoggerResetOutputBuffer(void);
extern u8* app_DectLoggerGetOutputBuffer(u16* pIndex);
#define CMBS_DECT_LOG_BUFF_SIZE (512)
u8 u8_gDectLogPrintBuffer[CMBS_DECT_LOG_BUFF_SIZE];
u16 u16_gDectLogPrintIndex;
void app_DectLoggerResetOutputBuffer(void)
{
u16_gDectLogPrintIndex = 0;
memset(u8_gDectLogPrintBuffer,0x0,sizeof(u8_gDectLogPrintBuffer));
}
//////////////////////////////////////////////////////////////////////////
u8* app_DectLoggerGetOutputBuffer(u16* pIndex)
{
* pIndex = u16_gDectLogPrintIndex;
return u8_gDectLogPrintBuffer;
}
//////////////////////////////////////////////////////////////////////////
E_CMBS_RC app_LogStartDectLogger( void )
{
return cmbs_dsr_StartDectLogger(g_cmbsappl.pv_CMBSRef);
}
//////////////////////////////////////////////////////////////////////////
E_CMBS_RC app_LogStoptDectLoggerAndRead( void )
{
return cmbs_dsr_StopDectLoggerAndRead(g_cmbsappl.pv_CMBSRef);
}
//////////////////////////////////////////////////////////////////////////
void app_DectLoggerDataInd(void * pv_EventData )
{
void * pv_IE = NULL;
u16 u16_IE;
ST_IE_DATA stData = {0,0};
u16 u16_Index=0,u16_PrintIndex=0,i;
u8 *pOutBuffer;
cmbs_api_ie_GetFirst( pv_EventData, &pv_IE, &u16_IE );
cmbs_api_ie_DataGet(pv_IE,&stData);
// check necessary conditions for continue processing
if ((stData.pu8_Data == NULL) ||(g_pDectLogFile == NULL))
return;
while (u16_Index < stData.u16_DataLen)
{
app_DectLoggerResetOutputBuffer();
cmbs_api_ParseDectMsg(&stData.pu8_Data[u16_Index+3],stData.pu8_Data[u16_Index],stData.pu8_Data[u16_Index+1]);
if (stData.pu8_Data[u16_Index+2] == 0)
{
fprintf(g_pDectLogFile,"\nTX BS --> HS%d ",stData.pu8_Data[u16_Index+1]);
}
else
{
fprintf(g_pDectLogFile,"\nRX BS <-- HS%d ",stData.pu8_Data[u16_Index+1]);
}
for (i=0;i<stData.pu8_Data[u16_Index];i++)
{
fprintf(g_pDectLogFile,"%x ",stData.pu8_Data[u16_Index+3+i]);
}
fprintf(g_pDectLogFile,"\n");
fflush(g_pDectLogFile);
pOutBuffer = app_DectLoggerGetOutputBuffer(&u16_PrintIndex);
if (g_pDectLogFile)
{
fwrite(pOutBuffer,1,u16_PrintIndex,g_pDectLogFile);
fflush(g_pDectLogFile);
}
u16_Index += (stData.pu8_Data[u16_Index]+3);
}
//No need to sedn response cmbs_dsr_DectLoggerDataIndRes(g_cmbsappl.pv_CMBSRef);
}
//////////////////////////////////////////////////////////////////////////
void app_DectLoggerStartResp(void * pv_EventData)
{
E_CMBS_RC retCode = app_ResponseCheck( pv_EventData ) ? CMBS_RC_ERROR_GENERAL : CMBS_RC_OK;
if (CMBS_RC_OK == retCode)
{
g_pDectLogFile = fopen("dect_scenario.log","w");
if (!g_pDectLogFile)
{
CFR_DBG_ERROR("\n Can't create output log file \n");
}
else
{
CFR_DBG_INFO("\n DectLogger started successfully \n");
}
}
else
{
CFR_DBG_ERROR("\n Error during starting DectLogger, maybe DECT_DBG not defined? ");
}
}
//////////////////////////////////////////////////////////////////////////
void app_DectLoggerStopResp(void * pv_EventData)
{
E_CMBS_RC retCode = app_ResponseCheck( pv_EventData ) ? CMBS_RC_ERROR_GENERAL : CMBS_RC_OK;
if (g_pDectLogFile)
{
fclose(g_pDectLogFile);
g_pDectLogFile = NULL;
}
if (CMBS_RC_OK == retCode)
{
CFR_DBG_INFO("\n DectLogger stopped successfully \n");
}
else
{
CFR_DBG_ERROR("\n Error during stopping DectLogger, maybe DECT_DBG not defined? \n");
}
}
//////////////////////////////////////////////////////////////////////////
int app_LogEntity( void * pv_AppRef, E_CMBS_EVENT_ID e_EventID, void * pv_EventData )
{
UNUSED_PARAMETER(pv_AppRef);
switch (e_EventID)
{
case CMBS_EV_DSR_START_DECT_LOGGER_RES:
app_DectLoggerStartResp(pv_EventData);
break;
case CMBS_EV_DSR_DECT_DATA_IND:
app_DectLoggerDataInd(pv_EventData);
break;
case CMBS_EV_DSR_STOP_AND_READ_DECT_LOGGER_RES:
app_DectLoggerStopResp(pv_EventData);
break;
default:
return FALSE;
break;
}
return TRUE;
}

View File

@@ -0,0 +1,31 @@
/*!
* \file applog.h
* \brief
* \Author podolskyi
*
* @(#) %filespec: applog.h~1 %
*
*******************************************************************************
* \par History
* \n==== History ============================================================\n
* date name version action \n
* ----------------------------------------------------------------------------\n
*******************************************************************************/
#if !defined( APPLOG_H )
#define APPLOG_H
#if defined( __cplusplus )
extern "C"
{
#endif
E_CMBS_RC app_LogStartDectLogger ( void );
E_CMBS_RC app_LogStoptDectLoggerAndRead ( void );
int app_LogEntity ( void * pv_AppRef, E_CMBS_EVENT_ID e_EventID, void * pv_EventData );
#if defined( __cplusplus )
}
#endif
#endif

Some files were not shown because too many files have changed in this diff Show More