Compare commits

...

44 Commits

Author SHA1 Message Date
Oron Peled
d5c95ea4dc xpp: improved waitfor_xpds
* Fix an issue due to long firmware load time:
  - When one Astribank has an echo canceler (long firmware loading) and
    and another one does not.
  - The EC-less Astribank finishes initialization before the Astribank
    with EC is detected.
  - Thus waitfor_xpds terminates too early.

* We now iteratively build two sets of serial numbers:
  - One from wha we see in all Xorcom (e4e4:11[3456]x) USB devices.
  - The other is those that were detected in the driver.
  - Only when the two sets are equal (and > 0) we know we are done.
  - This is resilient to many problems (e.g: disconnect/reconnect of
    same device during initialization).

* The progress output was also improved: Now each detected AB
  show the total number so far.

* The timeout was also increased to 100sec

* Woraround for an Astribank with no serial (but just a single one on
  the system).

Signed-off-by: Oron Peled <oron.peled@xorcom.com>
Acked-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10465

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/branches/2.6@10737 17933a7a-c749-41c5-a318-cba88f637d49
2012-11-22 16:55:38 +00:00
Tzafrir Cohen
ccff8dce20 README.Astribank: load module => module load
Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10701

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/branches/2.6@10703 17933a7a-c749-41c5-a318-cba88f637d49
2012-07-29 12:09:57 +00:00
Shaun Ruffell
663c07ed72 dahdi_hardware: Detect the Digium TE820 card.
Adding the TE820 vendor and device ID into PCI.pm allows dahdi_hardware to
recognize the card.

Reported-by: Xavier Hienne
Internal-Issue-ID: DAHTOOL-58
Signed-off-by: Shaun Ruffell <sruffell@digium.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10680

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/branches/2.6@10682 17933a7a-c749-41c5-a318-cba88f637d49
2012-05-14 16:43:11 +00:00
Oron Peled
b6fc15cc51 xpp: astribank_hook: wait for udev to settle
When running the astribank_hook (only on Astribanks, in XPP_HOTPLUG_DAHDI
mode), wait for all other Astribanks to create all the required device
files.

Signed-off-by: Oron Peled <oron.peled@xorcom.com>
Acked-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10585

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/branches/2.6@10596 17933a7a-c749-41c5-a318-cba88f637d49
2012-03-22 19:01:32 +00:00
Tzafrir Cohen
c66829844d xpp: astribank_allow: useless debug on write
Remove a useless debug message in the "write" operation.

Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10549

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/branches/2.6@10555 17933a7a-c749-41c5-a318-cba88f637d49
2012-03-20 11:53:14 +00:00
Tzafrir Cohen
b3ed010d76 xpp: fix build warnings
Unlike original: also fixed fpga_load.

Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10543

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/branches/2.6@10548 17933a7a-c749-41c5-a318-cba88f637d49
2012-03-20 06:27:21 +00:00
Tzafrir Cohen
3c263cdefd xpp: oct612x: fix build warnings
Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10542

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/branches/2.6@10547 17933a7a-c749-41c5-a318-cba88f637d49
2012-03-20 06:24:57 +00:00
Oron Peled
ea7688cf95 xpp: Update product ID's in Dahdi::Hardware::USB
Signed-off-by: Oron Peled <oron.peled@xorcom.com>
Acked-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>
Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10505

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/branches/2.6@10523 17933a7a-c749-41c5-a318-cba88f637d49
2012-03-15 21:49:23 +00:00
Oron Peled
94452be4a1 xpp: fix manpage of astribank_hexload
* Fixed 'astribanks_tool' string

Signed-off-by: Oron Peled <oron.peled@xorcom.com>
Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10503

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/branches/2.6@10522 17933a7a-c749-41c5-a318-cba88f637d49
2012-03-15 21:47:33 +00:00
Oron Peled
c7ab9d16e2 xpp: Customizable license markers
* License strings markers (BEGIN.../END...) can be customized
* By default, generate a "generic" license markers
* We accept any (paired) markers from the valid list

Signed-off-by: Oron Peled <oron.peled@xorcom.com>
Acked-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>
Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10502

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/branches/2.6@10521 17933a7a-c749-41c5-a318-cba88f637d49
2012-03-15 21:47:11 +00:00
Oron Peled
12c512c6d0 xpp: bugfix: handle echo_loader errors
* I/O errors of the device were not propagated up by echo_loader
* As a result, Octasic load failure did not prevented USB renumeration
* Make consistent return values:
  - In our functions: ret < 0 is error
  - In Octasic functions (UINT32): return Octasic error codes
* All error paths prints error messages (so we see how the error propagates)
* Also changed error order testing in init_octasic():
  Return status should be tested before the values of by-reference parameters

Signed-off-by: Oron Peled <oron.peled@xorcom.com>
Acked-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>
Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10499

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/branches/2.6@10520 17933a7a-c749-41c5-a318-cba88f637d49
2012-03-15 21:46:38 +00:00
Oron Peled
bf019b45ec xpp: echo_loader.c: add AB id to messages
* Define new macros AB_INFO(), AB_ERR() that prefix their message
  with the astribank information (usb device + serial number)
* Replace all INFO()/ERR() messages in echo_loader.c with the new macros

Signed-off-by: Oron Peled <oron.peled@xorcom.com>
Acked-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>
Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10498

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/branches/2.6@10519 17933a7a-c749-41c5-a318-cba88f637d49
2012-03-15 21:46:08 +00:00
Oron Peled
b053015f31 improve build_tools/dump_sys_state
* Use the new dahdi_sysfs_copy script
* Clean old/unused code
* Add notification output
* Now always creates a tarball - the gzipped copy is many times smaller.
* Without arguments, tarball name is:
    sys_dump.<hostname>_<date>_<time>.tar.gz

Signed-off-by: Oron Peled <oron.peled@xorcom.com>
Acked-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>
Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10497

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/branches/2.6@10518 17933a7a-c749-41c5-a318-cba88f637d49
2012-03-15 21:45:17 +00:00
Oron Peled
a8fc779e38 new build_tools/dahdi_sysfs_copy
Short perl script to copy dahdi related sysfs trees
into a designated directory.

Signed-off-by: Oron Peled <oron.peled@xorcom.com>
Acked-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>
Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10496

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/branches/2.6@10517 17933a7a-c749-41c5-a318-cba88f637d49
2012-03-15 21:44:35 +00:00
Oron Peled
34b51581d3 xpp: xpp_fxloader: improve output
* Replaced (almost) all $LOGGER to echo:
  - In interactive use -- that what we want anyway
  - When called from UDEV, the subprocess stdout/stderr is piped to
    $LOGGER anyway (at the end of the script)
  - No need for many $LOGGER instances (each with its own pid)

Signed-off-by: Oron Peled <oron.peled@xorcom.com>
Acked-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>
Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10495

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/branches/2.6@10516 17933a7a-c749-41c5-a318-cba88f637d49
2012-03-15 21:43:59 +00:00
Oron Peled
ff4048990d xpp: clean 'Extrainfo' EEPROM field
* Extrainfo field contains junk data
* Caused by:
  - The field is initialized to 0xFF values
  - There was no null termination (and no room to add it)
* New code:
  - Ensure that show_extrainfo() have null termination even if EEPROM
    field is full.
  - Replace trailing 0xFF characters with '\0' when reading this field
  - Since our default burned EEPROM contain Extrainfo field full of
    0xFF characters, this would make them look as null filled.

Internal Issue-Id: #1341
Signed-off-by: Oron Peled <oron.peled@xorcom.com>
Acked-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>
Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10491

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/branches/2.6@10515 17933a7a-c749-41c5-a318-cba88f637d49
2012-03-15 21:43:25 +00:00
Shaun Ruffell
05e271619b Creating branch for 2.6
git-svn-id: http://svn.astersk.org/svn/dahdi/tools/branches/2.6@10407 17933a7a-c749-41c5-a318-cba88f637d49
2012-01-04 22:20:25 +00:00
Tzafrir Cohen
dfa7a08ba3 xpp: two extra product IDs: 1112, 1164
Two extra USB product IDs used in some odd maintenance scenarios.

Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/trunk@10368 17933a7a-c749-41c5-a318-cba88f637d49
2011-12-04 17:08:29 +00:00
Tzafrir Cohen
32b715d373 xpp: xpp_fxloader: regressions from r10348
* Avoid a duplicated run of udev on some systems.
* Fix usage of astribank_tool's output.

Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/trunk@10366 17933a7a-c749-41c5-a318-cba88f637d49
2011-12-04 15:33:21 +00:00
Tzafrir Cohen
03c0afef41 DAHDI-perl: Fix PCI ID for Rhino R4T1 (0b0b:0305)
(Closes issue DAHTOOL-56)

Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/trunk@10358 17933a7a-c749-41c5-a318-cba88f637d49
2011-11-30 20:15:33 +00:00
Tzafrir Cohen
1b9a64e43b xpp: recovery firmware in xpp_fxloader
USB_RECOV.hex is an extra firmware that may be useful for recovering
from certain Astribank hardware faults in some scenarios. This adds
support for either loading it manually
('/usr/share/dahdi/xpp_fxloader recover-sb') or through udev, *if*
the required udev rules were set on the system.

Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/trunk@10349 17933a7a-c749-41c5-a318-cba88f637d49
2011-11-29 23:40:50 +00:00
Tzafrir Cohen
e6c2b1850d xpp: Serialized Parallel load; E-Main-3 firmware
This introduces support for loading multiple firmwares in parallel also
for the case of a manual load. This is anyway the case for an automatic
load from udev.

* libusb needs to scan the bus all too often. This causes occasional
  failures for opening devices.
* Thus introduce a semaphore to serialize uses of libusb.

E-Main-3 firmware differs by a different value of bcdDevice:

* Read this from the sysfs devices tree.
* Fall back to lsusb -v (much slower) is sysfs not available.

Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/trunk@10348 17933a7a-c749-41c5-a318-cba88f637d49
2011-11-29 23:40:21 +00:00
Tzafrir Cohen
29280a548c xpp: astribank_hexload: we need more lines
* Newer firmwares may have more lines.
* While we're at it, add better debug printing.
* Remove some unused debugging code.

Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/trunk@10343 17933a7a-c749-41c5-a318-cba88f637d49
2011-11-21 15:25:43 +00:00
Tzafrir Cohen
b093554f54 Fix GCC 4.6 "set but not used" warnings
Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/trunk@10311 17933a7a-c749-41c5-a318-cba88f637d49
2011-11-02 21:57:25 +00:00
Shaun Ruffell
bc6250fe1f dahdi_genconf: Allow it to recognize the TE8xx 8-port cards.
Signed-off-by: Shaun Ruffell <sruffell@digium.com>

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/trunk@10308 17933a7a-c749-41c5-a318-cba88f637d49
2011-11-02 20:55:52 +00:00
Oron Peled
ba070152fc dahdi_cfg: add '-S <spanno>' and '-C <chan-ranges>'
* dahdi_cfg -S <num>: only apply changes to span <num>.
* If span is analog (no 'span=<num>,<channels>,...' statement in
  system.conf), we need to set range: -C <channels>
* With the <basechan> and <channels> attributes in sysfs
  we easily configure each device on the fly.
  Simply run: dahdi_cfg -S <spanno> -C <basechan>+<channels>-1
  from udev script

Signed-off-by: Oron Peled <oron.peled@xorcom.com>
Acked-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/trunk@10306 17933a7a-c749-41c5-a318-cba88f637d49
2011-11-02 20:10:06 +00:00
Torrey Searle
541435eac7 dahdi_pcap: Imported user space utility for managing pcap streams
This utility will export packet captures for channels in dahdi. It requires
CONFIG_DAHDI_MIRROR to be defined in dahdi-linux as it uses the unsupported
DAHDI_MIRROR ioctl interface.

Internal-Issue-ID: DAHTOOL-49
From: Torrey Searle <tsearle@gmail.com>
Signed-off-by: Russ Meyerriecks <rmeyerriecks@digium.com>
Acked-by: Shaun Ruffell <sruffell@digium.com>

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/trunk@10293 17933a7a-c749-41c5-a318-cba88f637d49
2011-11-01 18:10:14 +00:00
Tzafrir Cohen
2457399d92 dahdi_perl: Use $Dahdi::sys_base for sysfs pathes
Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/trunk@10267 17933a7a-c749-41c5-a318-cba88f637d49
2011-10-23 14:43:27 +00:00
Tzafrir Cohen
a81a43c9b6 xpp_order generator: ignore EC XPD
The xpp_order configuration generator should only loop over telephony
devices, not all spans.

Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/trunk@10266 17933a7a-c749-41c5-a318-cba88f637d49
2011-10-23 14:28:40 +00:00
Tzafrir Cohen
5efd590aef chandahdi gen: extens can have any num of digits
Don't force extens we generate to have exactly 4 digits (simple
formatting limitation).

Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/trunk@10265 17933a7a-c749-41c5-a318-cba88f637d49
2011-10-23 14:23:17 +00:00
Tzafrir Cohen
1e21cb1356 Typos in man pages: toolyou
Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/trunk@10264 17933a7a-c749-41c5-a318-cba88f637d49
2011-10-23 14:22:05 +00:00
Shaun Ruffell
78584da122 dahdi_test: Enforce range from 0.0% - 100.0% for accuracy.
Also makes sure that the percentage output from the verbose and
non-verbose modes of timer_test are the same and print a cumulative
accuracy which smooths out the jitter for each pass.

If the time it takes to read in 1 second worth of data is longer than 1
second  accuracy will be 0%.

(closes issue #18573)
Reported by: smurfix

Signed-off-by: Shaun Ruffell <sruffell@digium.com>

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/trunk@10216 17933a7a-c749-41c5-a318-cba88f637d49
2011-09-29 17:00:59 +00:00
Shaun Ruffell
cbb0252a6a dahdi_maint: Print 'unsupported' warning if framing errors is -1.
Warn the user if attempting to monitor a statistic that the particular
board driver does not appear to be collecting. The wcte12xp in r10212 in
now fills in -1 for any statistic it does not collect and other digital
cards can do the same.

Signed-off-by: Shaun Ruffell <sruffell@digium.com>
Acked-by: Russ Meyerriecks <rmeyerriecks@digium.com>

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/trunk@10215 17933a7a-c749-41c5-a318-cba88f637d49
2011-09-29 17:00:55 +00:00
Shaun Ruffell
250bc06238 dahdi_genconf: Use 'dahdi_scan' to determine span_type for B410P cards.
The wcb4xxp driver does not put enough information in the proc filesystem to
determine if the ports are in TE or NT mode.  Previously the ports would
always just setup the dahdi-channels.conf file in TE mode. After this change
the dahdi_scan utility is used to detect if the ports are in TE or NT mode and
setup dahdi-channels.conf appropriately.

Internal-Issue-ID: DAHTOOL-54
Signed-off-by: Shaun Ruffell <sruffell@digium.com>

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/trunk@10214 17933a7a-c749-41c5-a318-cba88f637d49
2011-09-29 17:00:51 +00:00
Shaun Ruffell
db9b649e03 dahdi_genconf: Assume spans with unknown term types are software selectable.
Resolves a regression on the 2.5 branch that would result in:

  $ dahdi_genconf
  dahdi_genconf: missing default group (termtype=UNKNOWN)

E1 / T1 spans use software configuration to set CPE / NET mode. This
patch will just assume that a termtype is software selectable if it was
"UNKNOWN" when first scanning the span.

Internal-Issue-ID: DAHTOOL-55
Signed-off-by: Shaun Ruffell <sruffell@digium.com>
Tested-by: David Purdue <support@noojee.com.au>

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/trunk@10213 17933a7a-c749-41c5-a318-cba88f637d49
2011-09-29 17:00:46 +00:00
Tzafrir Cohen
2d576dcea0 Man page for dahdi_maint
Fix dahdi_maint's usage message while we're at it.

Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/trunk@10198 17933a7a-c749-41c5-a318-cba88f637d49
2011-09-09 13:45:00 +00:00
Tzafrir Cohen
b487a96ada Update the dahdi-monitor man page
Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/trunk@10196 17933a7a-c749-41c5-a318-cba88f637d49
2011-09-09 12:04:34 +00:00
Tzafrir Cohen
67cc13f100 fix typos in some xpp utils
Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/trunk@10194 17933a7a-c749-41c5-a318-cba88f637d49
2011-09-09 10:59:39 +00:00
Tzafrir Cohen
3482a25b84 xpp: waitfor_xpds: higher and configurable timeout
On several pathological cases we may need to wait more than 40 seconds.
Make that timeout configurable.

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/trunk@10177 17933a7a-c749-41c5-a318-cba88f637d49
2011-09-05 09:05:48 +00:00
Oron Peled
b23f3ca5a9 dahdi-perl: Also get USB loaded driver from usbfs
Signed-off-by: Oron Peled <oron.peled@xorcom.com>
Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/trunk@10153 17933a7a-c749-41c5-a318-cba88f637d49
2011-08-25 10:32:17 +00:00
Tzafrir Cohen
a5c6e58b6e dahdi-perl: Freepbxdb config generator
Use 'dahdi_genconf freepbxdb' to generate the required astdb entries
for Asterisk to use the extensions generated by dahdi_genconf. Requires
asterisk to be running.

This module is intended for testing as it bypasses standard FreePBX
functions only and hence may not work properly with Freepbx.

Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/trunk@10142 17933a7a-c749-41c5-a318-cba88f637d49
2011-08-18 15:38:45 +00:00
Tzafrir Cohen
12492f4e23 README.Astribank: HWEC and build instructions
Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/trunk@10104 17933a7a-c749-41c5-a318-cba88f637d49
2011-08-10 15:31:22 +00:00
Tzafrir Cohen
2061c6c359 xpp: pri_termtype: match complete SPAN patterns
Match complete span patterns, to avoid pattern 'SPAN/1' from matching
e.g. span 12 (SPAN/12).

Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/trunk@10101 17933a7a-c749-41c5-a318-cba88f637d49
2011-08-09 13:11:20 +00:00
Tzafrir Cohen
bad2f86c11 Extra README fixes: 'th' and ztcfg
Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/trunk@10087 17933a7a-c749-41c5-a318-cba88f637d49
2011-08-02 17:28:23 +00:00
47 changed files with 2124 additions and 771 deletions

View File

@@ -176,6 +176,9 @@ $(LTZ_SO): $(LTZ_SO_OBJS)
dahdi_cfg: $(LTZ_A)
dahdi_cfg: LIBS+=-lm
dahdi_pcap:
$(CC) $(CFLAGS) dahdi_pcap.c -lpcap -o $@ $<
fxstest: $(LTZ_SO)
fxstest: LIBS+=-lm
@@ -345,6 +348,7 @@ clean:
rm -f core
rm -f dahdi_cfg-shared fxstest
rm -rf $(GENERATED_DOCS) *.asciidoc tonezones.txt
rm -f dahdi_pcap
distclean: dist-clean

4
README
View File

@@ -66,7 +66,7 @@ Installation to a Subtree
^^^^^^^^^^^^^^^^^^^^^^^^^
The following may be useful when testing the package or when preparing a
package for a binary distribution (such as an rpm package) installing
onto a subtree rather than on th real system.
onto a subtree rather than on the real system.
make install DESTDIR=targetdir
@@ -138,7 +138,7 @@ include::genconf_parameters.asciidoc[]
Tonezones
~~~~~~~~~
The file zonedata.c contains the information about the tone zones used
in libtonezone (and hence also in ztcfg). Here is a list of those zones:
in libtonezone (and hence also in dahdi_cfg). Here is a list of those zones:
include::tonezones.txt[]

142
build_tools/dahdi_sysfs_copy Executable file
View File

@@ -0,0 +1,142 @@
#! /usr/bin/perl
#
# Written by Oron Peled <oron@actcom.co.il>
# Copyright (C) 2012, Xorcom
# This program is free software; you can redistribute and/or
# modify it under the same terms as Perl itself.
#
#dahdi_sysfs_copy: Short perl script to copy dahdi related sysfs trees
# into a designated directory.
#
# $Id: $
#
use strict;
use warnings;
use File::Path qw(mkpath);
use File::Copy;
use Cwd qw(realpath);
my $destdir = shift || die "Usage: $0 <destdir>\n";
my %symlinks;
my %walk_ups;
my %inode_cash;
# Starting points for recursion
my @toplevels = qw(
/sys/bus/dahdi_devices
/sys/bus/astribanks
/sys/class/dahdi
);
# Loop prevention (by inode number lookup)
sub seen {
my $ino = shift || die;
my $path = shift || die;
if(defined $inode_cash{$ino}) {
#print STDERR "DEBUG($ino): $path\n";
return 1;
}
$inode_cash{$ino}++;
return 0;
}
# Walk up a path and copy readable attributes from any
# directory level.
sub walk_up {
my $path = shift || die;
my $curr = $path;
# Walk up
for (my $curr = $path; $curr; $curr =~ s'/?[^/]+$'') {
my ($dev, $ino, $mode, $nlink, $uid, $gid) = lstat($curr);
next if seen($ino, $curr); # Skip visited directories
# Scan directory
opendir(my $d, $curr) || die "Failed opendir($curr): $!\n";
my @entries = readdir $d;
foreach my $entry (@entries) {
next if $entry =~ /^[.][.]?$/;
my $file = "$curr/$entry";
my ($dev, $ino, $mode, $nlink, $uid, $gid) = lstat($file);
# Copy file
if (-f _ && ($mode & 0004)) { # The '-r _' is buggy
copy($file, "$destdir$file") ||
die "Failed to copy '$file': $!\n";
}
}
closedir $d;
}
}
# Handle a given path (directory,symlink,regular-file)
sub handle_path {
my $path = shift || die;
my ($dev, $ino, $mode, $nlink, $uid, $gid) = lstat($path);
# Save attributes before recursion starts
my $isdir = -d _;
my $islink = -l _;
my $isreadable = $mode & 00004; # The '-r _' was buggy
return if seen($ino, $path); # Loop prevention
my $dest = "$destdir/$path";
if ($isdir) {
mkpath("$dest");
scan_directory($path);
} elsif ($islink) {
# We follow links (the seen() protect us from loops)
my $target = readlink($path) ||
die "Failed readlink($path): $!\n";
my $follow = $target;
if ($target !~ m{^/}) { # fix relative symlinks
my $dir = $path;
$dir =~ s,/[^/]*$,,;
$follow = realpath("$dir/$target");
}
# Save symlink details, so we create them after all
# destination tree (subdirectories, files) is ready
die "Duplicate entry '$dest'\n" if exists $symlinks{$dest};
$symlinks{$dest} = "$target";
# Now follow symlink
handle_path($follow);
$walk_ups{$follow}++;
} elsif ($isreadable) {
copy($path, "$dest") ||
die "Failed to copy '$path': $!\n";
}
}
# Scan a given directory (calling handle_path for recursion)
sub scan_directory {
my $dir = shift || die;
my $entry;
opendir(my $d, $dir) || die "Failed opendir($dir): $!\n";
my @dirs = readdir $d;
foreach my $entry (@dirs) {
next if $entry =~ /^[.][.]?$/;
handle_path("$dir/$entry");
}
closedir $d;
}
# Filter out non-existing toplevels
my @scan = grep { lstat($_) } @toplevels;
# Recurse all trees, creating subdirectories and copying files
foreach my $path (@scan) {
handle_path($path);
}
# Now, that all sub-directories were created, we can
# create the wanted symlinks
for my $dest (keys %symlinks) {
my $link = $symlinks{$dest};
die "Missing link for '$dest'\n" unless defined $link;
unlink $dest if -l $dest;
symlink($link,$dest) ||
die "Failed symlink($link,$dest): $!\n";
}
# Walk up directories that were symlink destinations
# and fill their attributes
foreach my $dir (keys %walk_ups) {
walk_up($dir);
}

View File

@@ -31,117 +31,46 @@
# # And then later:
# DAHDI_VIRT_TOP="$PWD/my_sys_state" dahdi_genconf
name=dahdi_sys_state_dump
usage() {
echo "$0: dump system data for Dahdi-Perl"
echo "Usage: $0 [<name>]]"
echo ""
echo "<name>: name of directory/tarball to create. Default: $name"
}
output_tar() {
gzip -9 >$name.tar.gz
}
output_cpio() {
gzip -9 >$name.cpio.gz
}
output_dir() {
rm -rf $name
mkdir -p $name
cd $name
#tar xf -
cpio -id
}
mydir=`dirname $0`
dahdi_sysfs_copy="$mydir/dahdi_sysfs_copy"
# Give usage message on expected texts
case $1 in
help | -* ) usage; exit 1;;
esac
if [ "$1" != '' ]; then
name="$1"
if [ "$#" -ne 0 ]; then
echo >&2 "Usage: $0"
exit 1
fi
# funky permissions on procfs. Sadly rm -f does not kill them.
if [ -d "$name" ]; then
chmod -R u+w "$name"
fi
rm -rf "$name"
mkdir -p "$name"
id="sys_dump.`hostname`_`date +%F_%H.%M.%S`"
tarball="$id.tar.gz"
# delete a (potentially empty) list of files
rm_files() {
xargs rm -f rm_files_non_existing_file
}
tmpdir=`mktemp -td 'dahdi_dump.XXXXXX'`
echo -n >&2 "Creating ... "
trap "[ -d '$tmpdir' ] && rm -rf '$tmpdir'" 0 1 2 15
topdir="$tmpdir/$id"
if [ -r /proc/bus/usb/devices ]; then
mkdir -p "$name/proc/bus/usb"
cp -a /proc/bus/usb/devices "$name/proc/bus/usb/"
mkdir -p "$topdir/proc/bus/usb"
cp -a /proc/bus/usb/devices "$topdir/proc/bus/usb/"
fi
if [ -d /proc/dahdi ]; then
mkdir -p "$name/proc/dahdi"
mkdir -p "$topdir/proc/dahdi"
if find /proc/dahdi -type f >/dev/null; then
cp -a /proc/dahdi/* "$name/proc/dahdi/"
cp -a /proc/dahdi/* "$topdir/proc/dahdi/"
fi
fi
if [ -d /proc/xpp ]; then
mkdir -p "$name/proc/xpp"
mkdir -p "$topdir/proc/xpp"
if find /proc/xpp -type f >/dev/null; then
cp -a /proc/xpp/* "$name/proc/xpp/"
find "$name/proc/xpp" -type f -name command | rm_files
cp -a /proc/xpp/* "$topdir/proc/xpp/"
find "$topdir/proc/xpp" -type f -name command -exec rm -f '{}' ';'
fi
fi
# FIXME: the following grab tons of files from sysfs. Any way to do with
# less information?
pci_dev_pat='/sys/devices/pci*'
mkdir -p "$name/sys/devices"
cp -a $pci_dev_pat "$name/sys/devices/" 2>/dev/null
for bus in astribanks xpds pci pci_express usb; do
if [ -d /sys/bus/$bus ]; then
mkdir -p "$name/sys/bus/"
cp -a /sys/bus/$bus "$name/sys/bus/" 2>/dev/null
fi
done
# Remove PCI devices of irelevan classes:
irrelevant_devs() {
grep . "$name"/$pci_dev_pat/0*/class "$name"/$pci_dev_pat/0*/0*/class \
| perl -n -e '# Perl provides commented regexes:
next unless m{/class:( # The following is a list of device classes
# that can be safely removed:
0x060000 | # Host bridge
0x030000 | # VGA compatible controller
0x038000 | # Display controller
0x040300 | # Audio device
0x060401 | # PCI bridge
0x060100 | # ISA bridge
0x01018a | # IDE interface
0x01018f | # IDE interface
0x0c0500 | # SMBus
0x060700 | # CardBus bridge
0x0c0010 | # FireWire (IEEE 1394)
# The following are not to be removed:
#0x0c0300 | # USB Controller (UHCI?)
#0x060400 | # PCI bridge
#0x0c0320 | # USB Controller (EHCI?)
#0x020000 | # Ethernet controller
#0x0c0010 | # Network controller: (Wifi?)
)$}x;
# Leave out just the name of the node:
s{/[^/]*$}{};
print;
print "\n"
'
}
# FIXME: deleting those seems to remove common 'vendor' directories
# and mess things up. Skip it for now.
#rm -rf `irrelevant_devs`
"$dahdi_sysfs_copy" "$topdir"
echo -n >&2 "tarball ... "
( cd "$tmpdir" && tar czf - . ) > "$tarball";
echo >&2 "ready in '$tarball'"

View File

@@ -85,6 +85,13 @@ static struct dahdi_lineconfig lc[DAHDI_MAX_SPANS];
static struct dahdi_chanconfig cc[DAHDI_MAX_CHANNELS];
static int current_span = 0;
static int only_span = 0;
static int restrict_channels = 0;
static int selected_channels[DAHDI_MAX_CHANNELS];
static int chan2span[DAHDI_MAX_CHANNELS];
static int declared_spans[DAHDI_MAX_SPANS];
static struct dahdi_attach_echocan ae[DAHDI_MAX_CHANNELS];
static struct dahdi_dynamic_span zds[NUM_DYNAMIC];
@@ -228,6 +235,35 @@ static char *trim(char *buf)
return buf;
}
static int skip_channel(int x)
{
int spanno = chan2span[x];
if (restrict_channels) {
if (!selected_channels[x])
return 1;
/* sanity check */
if (only_span) {
if (spanno != 0 && only_span != spanno) {
fprintf(stderr,
"Only span %d. Skip selected channel %d from span %d\n",
only_span, x, spanno);
return 1;
}
}
} else {
if (only_span && !declared_spans[only_span]) {
fprintf(stderr,
"Error: analog span %d given to '-S', without '-C' restriction.\n",
only_span);
exit(1);
}
if (only_span && only_span != spanno)
return 1;
}
return 0;
}
static int parseargs(char *input, char *output[], int maxargs, char sep)
{
char *c;
@@ -258,11 +294,10 @@ static int parseargs(char *input, char *output[], int maxargs, char sep)
int dspanconfig(char *keyword, char *args)
{
static char *realargs[10];
int argc;
int res;
int chans;
int timing;
argc = res = parseargs(args, realargs, 4, ',');
res = parseargs(args, realargs, 4, ',');
if (res != 4) {
error("Incorrect number of arguments to 'dynamic' (should be <driver>,<address>,<num channels>, <timing>)\n");
return -1;
@@ -311,6 +346,8 @@ int spanconfig(char *keyword, char *args)
error("Span number should be a valid span number, not '%s'\n", realargs[0]);
return -1;
}
current_span = span;
declared_spans[span] = 1;
res = sscanf(realargs[1], "%d", &timing);
if ((res != 1) || (timing < 0) || (timing > MAX_TIMING)) {
error("Timing should be a number from 0 to %d, not '%s'\n",
@@ -482,6 +519,7 @@ static int chanconfig(char *keyword, char *args)
int master=0;
int dacschan = 0;
char *idle;
int is_digital;
bzero(chans, sizeof(chans));
strtok(args, ":");
idle = strtok(NULL, ":");
@@ -493,6 +531,7 @@ static int chanconfig(char *keyword, char *args)
if (res <= 0)
return -1;
for (x=1;x<DAHDI_MAX_CHANNELS;x++) {
is_digital = 0;
if (chans[x]) {
if (slineno[x]) {
error("Channel %d already configured as '%s' at line %d\n", x, sig[x], slineno[x]);
@@ -538,6 +577,7 @@ static int chanconfig(char *keyword, char *args)
return -1;
cc[x].sigtype = DAHDI_SIG_CAS;
sig[x] = sigtype_to_str(cc[x].sigtype);
is_digital = 1;
} else if (!strcasecmp(keyword, "dacs")) {
/* Setup channel for monitor */
cc[x].idlebits = dacschan;
@@ -548,6 +588,7 @@ static int chanconfig(char *keyword, char *args)
cc[dacschan].sigtype = DAHDI_SIG_DACS;
sig[x] = sigtype_to_str(cc[dacschan].sigtype);
dacschan++;
is_digital = 1;
} else if (!strcasecmp(keyword, "dacsrbs")) {
/* Setup channel for monitor */
cc[x].idlebits = dacschan;
@@ -557,6 +598,7 @@ static int chanconfig(char *keyword, char *args)
cc[dacschan].idlebits = x;
cc[dacschan].sigtype = DAHDI_SIG_DACS_RBS;
sig[x] = sigtype_to_str(cc[dacschan].sigtype);
is_digital = 1;
dacschan++;
} else if (!strcasecmp(keyword, "unused")) {
cc[x].sigtype = 0;
@@ -564,6 +606,7 @@ static int chanconfig(char *keyword, char *args)
} else if (!strcasecmp(keyword, "indclear") || !strcasecmp(keyword, "bchan")) {
cc[x].sigtype = DAHDI_SIG_CLEAR;
sig[x] = sigtype_to_str(cc[x].sigtype);
is_digital = 1;
} else if (!strcasecmp(keyword, "clear")) {
sig[x] = sigtype_to_str(DAHDI_SIG_CLEAR);
if (master) {
@@ -573,6 +616,7 @@ static int chanconfig(char *keyword, char *args)
cc[x].sigtype = DAHDI_SIG_CLEAR;
master = x;
}
is_digital = 1;
} else if (!strcasecmp(keyword, "rawhdlc")) {
sig[x] = sigtype_to_str(DAHDI_SIG_HDLCRAW);
if (master) {
@@ -582,6 +626,7 @@ static int chanconfig(char *keyword, char *args)
cc[x].sigtype = DAHDI_SIG_HDLCRAW;
master = x;
}
is_digital = 1;
} else if (!strcasecmp(keyword, "nethdlc")) {
sig[x] = sigtype_to_str(DAHDI_SIG_HDLCNET);
memset(cc[x].netdev_name, 0, sizeof(cc[x].netdev_name));
@@ -595,6 +640,7 @@ static int chanconfig(char *keyword, char *args)
}
master = x;
}
is_digital = 1;
} else if (!strcasecmp(keyword, "fcshdlc")) {
sig[x] = sigtype_to_str(DAHDI_SIG_HDLCFCS);
if (master) {
@@ -604,18 +650,26 @@ static int chanconfig(char *keyword, char *args)
cc[x].sigtype = DAHDI_SIG_HDLCFCS;
master = x;
}
is_digital = 1;
} else if (!strcasecmp(keyword, "dchan")) {
sig[x] = "D-channel";
cc[x].sigtype = DAHDI_SIG_HDLCFCS;
is_digital = 1;
} else if (!strcasecmp(keyword, "hardhdlc")) {
sig[x] = "Hardware assisted D-channel";
cc[x].sigtype = DAHDI_SIG_HARDHDLC;
is_digital = 1;
} else if (!strcasecmp(keyword, "mtp2")) {
sig[x] = "MTP2";
cc[x].sigtype = DAHDI_SIG_MTP2;
is_digital = 1;
} else {
fprintf(stderr, "Huh? (%s)\n", keyword);
}
if (is_digital)
chan2span[x] = current_span;
else
current_span = 0;
}
}
return 0;
@@ -667,6 +721,8 @@ static void apply_fiftysix(void)
int chanfd;
for (x = 1; x < DAHDI_MAX_CHANNELS; x++) {
if (skip_channel(x))
continue;
chanfd = open("/dev/dahdi/channel", O_RDWR);
if (chanfd == -1) {
fprintf(stderr,
@@ -755,13 +811,12 @@ static int unimplemented(char *keyword, char *args)
int ctcss(char *keyword, char *args)
{
static char *realargs[10];
int argc;
int res;
int rxtone;
int rxtag;
int txtone;
int isdcs = 0;
argc = res = parseargs(args, realargs, 3, ',');
res = parseargs(args, realargs, 3, ',');
if (res != 3) {
error("Incorrect number of arguments to 'ctcss' (should be <rxtone>,<rxtag>,<txtone>)\n");
return -1;
@@ -808,10 +863,9 @@ int ctcss(char *keyword, char *args)
int dcsrx(char *keyword, char *args)
{
static char *realargs[10];
int argc;
int res;
int rxtone;
argc = res = parseargs(args, realargs, 1, ',');
res = parseargs(args, realargs, 1, ',');
if (res != 1) {
error("Incorrect number of arguments to 'dcsrx' (should be <rxtone>)\n");
return -1;
@@ -831,11 +885,10 @@ int dcsrx(char *keyword, char *args)
int tx(char *keyword, char *args)
{
static char *realargs[10];
int argc;
int res;
int txtone;
int isdcs = 0;
argc = res = parseargs(args, realargs, 1, ',');
res = parseargs(args, realargs, 1, ',');
if (res != 1) {
error("Incorrect number of arguments to 'tx' (should be <txtone>)\n");
return -1;
@@ -860,10 +913,9 @@ int tx(char *keyword, char *args)
int debounce_time(char *keyword, char *args)
{
static char *realargs[10];
int argc;
int res;
int val;
argc = res = parseargs(args, realargs, 1, ',');
res = parseargs(args, realargs, 1, ',');
if (res != 1) {
error("Incorrect number of arguments to 'debouncetime' (should be <value>)\n");
return -1;
@@ -883,10 +935,9 @@ int debounce_time(char *keyword, char *args)
int burst_time(char *keyword, char *args)
{
static char *realargs[10];
int argc;
int res;
int val;
argc = res = parseargs(args, realargs, 1, ',');
res = parseargs(args, realargs, 1, ',');
if (res != 1) {
error("Incorrect number of arguments to 'bursttime' (should be <value>)\n");
return -1;
@@ -906,10 +957,9 @@ int burst_time(char *keyword, char *args)
int tx_gain(char *keyword, char *args)
{
static char *realargs[10];
int argc;
int res;
int val;
argc = res = parseargs(args, realargs, 1, ',');
res = parseargs(args, realargs, 1, ',');
if (res != 1) {
error("Incorrect number of arguments to 'txgain' (should be <value>)\n");
return -1;
@@ -927,10 +977,9 @@ int tx_gain(char *keyword, char *args)
int rx_gain(char *keyword, char *args)
{
static char *realargs[10];
int argc;
int res;
int val;
argc = res = parseargs(args, realargs, 1, ',');
res = parseargs(args, realargs, 1, ',');
if (res != 1) {
error("Incorrect number of arguments to 'rxgain' (should be <value>)\n");
return -1;
@@ -948,10 +997,9 @@ int rx_gain(char *keyword, char *args)
int de_emp(char *keyword, char *args)
{
static char *realargs[10];
int argc;
int res;
int val;
argc = res = parseargs(args, realargs, 1, ',');
res = parseargs(args, realargs, 1, ',');
if (res != 1) {
error("Incorrect number of arguments to 'de-emp' (should be <value>)\n");
return -1;
@@ -971,10 +1019,9 @@ int de_emp(char *keyword, char *args)
int pre_emp(char *keyword, char *args)
{
static char *realargs[10];
int argc;
int res;
int val;
argc = res = parseargs(args, realargs, 1, ',');
res = parseargs(args, realargs, 1, ',');
if (res != 1) {
error("Incorrect number of arguments to 'pre_emp' (should be <value>)\n");
return -1;
@@ -994,10 +1041,9 @@ int pre_emp(char *keyword, char *args)
int invert_cor(char *keyword, char *args)
{
static char *realargs[10];
int argc;
int res;
int val;
argc = res = parseargs(args, realargs, 1, ',');
res = parseargs(args, realargs, 1, ',');
if (res != 1) {
error("Incorrect number of arguments to 'invertcor' (should be <value>)\n");
return -1;
@@ -1021,10 +1067,9 @@ int invert_cor(char *keyword, char *args)
int ext_tone(char *keyword, char *args)
{
static char *realargs[10];
int argc;
int res;
int val;
argc = res = parseargs(args, realargs, 1, ',');
res = parseargs(args, realargs, 1, ',');
if (res != 1) {
error("Incorrect number of arguments to 'exttone' (should be <value>)\n");
return -1;
@@ -1050,11 +1095,10 @@ int ext_tone(char *keyword, char *args)
int cor_thresh(char *keyword, char *args)
{
static char *realargs[10];
int argc;
int res;
int val;
int x = 0;
argc = res = parseargs(args, realargs, 1, ',');
res = parseargs(args, realargs, 1, ',');
if (res != 1) {
error("Incorrect number of arguments to 'corthresh' (should be <value>)\n");
return -1;
@@ -1227,6 +1271,8 @@ static void printconfig(int fd)
"Configuration\n"
"======================\n\n", vi.version, vi.echo_canceller);
for (x = 0; x < spans; x++) {
if (only_span && only_span != x)
continue;
printf("SPAN %d: %3s/%4s Build-out: %s\n",
lc[x].span,
(lc[x].lineconfig & DAHDI_CONFIG_D4 ? "D4" :
@@ -1244,6 +1290,8 @@ static void printconfig(int fd)
if (verbose > 1) {
printf("\nChannel map:\n\n");
for (x=1;x<DAHDI_MAX_CHANNELS;x++) {
if (skip_channel(x))
continue;
if ((cc[x].sigtype != DAHDI_SIG_SLAVE) && (cc[x].sigtype)) {
configs++;
ps = 0;
@@ -1267,6 +1315,8 @@ static void printconfig(int fd)
}
} else {
for (x=1;x<DAHDI_MAX_CHANNELS;x++) {
if (skip_channel(x))
continue;
if (cc[x].sigtype)
configs++;
}
@@ -1361,11 +1411,39 @@ static void usage(char *argv0, int exitcode)
" -h -- Generate this help statement\n"
" -s -- Shutdown spans only\n"
" -t -- Test mode only, do not apply\n"
" -C <chan_list> -- Only configure specified channels\n"
" -S <spanno> -- Only configure specified span\n"
" -v -- Verbose (more -v's means more verbose)\n"
,c);
exit(exitcode);
}
static int chan_restrict(char *str)
{
if (apply_channels(selected_channels, str) < 0)
return 0;
restrict_channels = 1;
return 1;
}
static int span_restrict(char *str)
{
long spanno;
char *endptr;
spanno = strtol(str, &endptr, 10);
if (endptr == str) {
fprintf(stderr, "Missing valid span number after '-S'\n");
return 0;
}
if (*endptr != '\0') {
fprintf(stderr, "Extra garbage after span number in '-S'\n");
return 0;
}
only_span = spanno;
return 1;
}
int main(int argc, char *argv[])
{
int c;
@@ -1373,7 +1451,7 @@ int main(int argc, char *argv[])
char *key, *value;
int x,found;
while((c = getopt(argc, argv, "fthc:vsd::")) != -1) {
while((c = getopt(argc, argv, "fthc:vsd::C:S:")) != -1) {
switch(c) {
case 'c':
filename=optarg;
@@ -1396,6 +1474,14 @@ int main(int argc, char *argv[])
case 's':
stopmode = 1;
break;
case 'C':
if (!chan_restrict(optarg))
usage(argv[0], 1);
break;
case 'S':
if (!span_restrict(optarg))
usage(argv[0], 1);
break;
case 'd':
if (optarg)
debug = atoi(optarg);
@@ -1478,6 +1564,8 @@ finish:
}
if (stopmode) {
for (x=0;x<spans;x++) {
if (only_span && x != only_span)
continue;
if (ioctl(fd, DAHDI_SHUTDOWN, &lc[x].span)) {
fprintf(stderr, "DAHDI shutdown failed: %s\n", strerror(errno));
close(fd);
@@ -1487,6 +1575,8 @@ finish:
exit(1);
}
for (x=0;x<spans;x++) {
if (only_span && x != only_span)
continue;
if (ioctl(fd, DAHDI_SPANCONFIG, lc + x)) {
fprintf(stderr, "DAHDI_SPANCONFIG failed on span %d: %s (%d)\n", lc[x].span, strerror(errno), errno);
close(fd);
@@ -1504,7 +1594,14 @@ finish:
struct dahdi_params current_state;
int master;
int needupdate = force;
if (skip_channel(x)) {
if (debug & DEBUG_APPLY) {
printf("Skip device %d\n", x);
fflush(stdout);
}
continue;
}
if (debug & DEBUG_APPLY) {
printf("Configuring device %d\n", x);
fflush(stdout);
@@ -1657,6 +1754,8 @@ finish:
}
}
for (x=0;x<spans;x++) {
if (only_span && x != only_span)
continue;
if (ioctl(fd, DAHDI_STARTUP, &lc[x].span)) {
fprintf(stderr, "DAHDI startup failed: %s\n", strerror(errno));
close(fd);

View File

@@ -53,12 +53,14 @@ void display_help(char *argv0, int exitcode)
fprintf(stderr, " -h, --help display help\n");
fprintf(stderr, " -s, --span <span num> specify the span\n");
fprintf(stderr, " -l, --loopback <localhost|networkline|"\
"networkpayload|off>\n"\
"networkpayload|loopup|"\
"loopdown|off>\n"\
"\t\tlocalhost - loop back towards host\n"\
"\t\tnetworkline - network line loopback\n"\
"\t\tnetworkpayload - network payload loopback\n"\
"\t\tloopup - transmit loopup signal\n"\
"\t\tloopdown - transmit loopdown signal\n");
"\t\tloopdown - transmit loopdown signal\n"\
"\t\toff - end loopback mode\n");
fprintf(stderr, " -i, --insert <fas|multi|crc|cas|prbs|bipolar>"\
"\n\t\tinsert an error of a specific type\n");
fprintf(stderr, " -r, --reset "\
@@ -79,7 +81,6 @@ int main(int argc, char *argv[])
int doloopback = 0;
char *larg = NULL;
int sflag = 0;
int span = 1;
int iflag = 0;
char *iarg = NULL;
@@ -107,16 +108,15 @@ int main(int argc, char *argv[])
while ((c = getopt_long(argc, argv, "hj:l:p:s:i:g:r",
long_options, &option_index)) != -1) {
switch (c) {
case 'h': /* local host loopback */
case 'h':
display_help(argv[0], 0);
break;
case 'l': /* network line loopback */
case 'l': /* loopback */
larg = optarg;
doloopback = 1;
break;
case 's': /* specify a span */
span = atoi(optarg);
sflag = 1;
break;
case 'i': /* insert an error */
iarg = optarg;
@@ -140,7 +140,7 @@ int main(int argc, char *argv[])
if (!(doloopback || iflag || gflag || rflag)) {
s.spanno = span;
res = ioctl(ctl, DAHDI_SPANSTAT, &s);
if (res)
if (res || ((__u32)-1 == s.fecount))
printf("Error counters not supported by the driver"\
" for this span\n");
printf("Span %d:\n", span);

332
dahdi_pcap.c Normal file
View File

@@ -0,0 +1,332 @@
/*
* Capturing a pcap from the DAHDI interface
*
* Copyright (C) 2011 Torrey Searle
*
* ISDN support added by Horacio Peña
* Command line cleanups by Sverker Abrahamsson
*
* Requirements:
* - pcap development library
* - DAHDI_MIRROR ioctl which isn't enabled by default in dahdi-linux
* To enable this unsupported feature, #define CONFIG_DAHDI_MIRROR
* in dahdi-linux
* - To build this program call the 'make dahdi_pcap' target
*/
/*
* See http://www.asterisk.org for more information about
* the Asterisk project. Please do not directly contact
* any of the maintainers of this project for assistance;
* the project provides a web site, mailing lists and IRC
* channels for your use.
*
* This program is free software, distributed under the terms of
* the GNU General Public License Version 2 as published by the
* Free Software Foundation. See the LICENSE file included with
* this program for more details.
*/
#include <stdio.h>
#include <fcntl.h>
#include <dahdi/user.h>
#include <sys/time.h>
#include <time.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <pcap.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <getopt.h>
#define BLOCK_SIZE 512
#define MAX_CHAN 16
//char ETH_P_LAPD[2] = {0x00, 0x30};
struct mtp2_phdr {
u_int8_t sent;
u_int8_t annex_a_used;
u_int16_t link_number;
};
struct lapd_sll_hdr {
u_int16_t sll_pkttype; /* packet type */
u_int16_t sll_hatype;
u_int16_t sll_halen;
u_int8_t sll_addr[8];
u_int8_t sll_protocol[2]; /* protocol, should be ETH_P_LAPD */
};
struct chan_fds {
int rfd;
int tfd;
int chan_id;
int proto;
char tx_buf[BLOCK_SIZE * 4];
int tx_len;
char rx_buf[BLOCK_SIZE * 4];
int rx_len;
};
int make_mirror(long type, int chan)
{
int res = 0;
int fd = 0;
struct dahdi_bufferinfo bi;
fd = open("/dev/dahdi/pseudo", O_RDONLY);
memset(&bi, 0, sizeof(bi));
bi.txbufpolicy = DAHDI_POLICY_IMMEDIATE;
bi.rxbufpolicy = DAHDI_POLICY_IMMEDIATE;
bi.numbufs = 32;
bi.bufsize = BLOCK_SIZE;
ioctl(fd, DAHDI_SET_BUFINFO, &bi);
res = ioctl(fd, type, &chan);
if(res)
{
printf("error setting channel err=%d!\n", res);
return -1;
}
return fd;
}
int log_packet(struct chan_fds * fd, char is_read, pcap_dumper_t * dump)
{
unsigned char buf[BLOCK_SIZE * 4];
int res = 0;
struct pcap_pkthdr hdr;
struct mtp2_phdr * mtp2 = (struct mtp2_phdr *)buf;
struct lapd_sll_hdr * lapd = (struct lapd_sll_hdr *)buf;
unsigned char *dataptr = buf;
int datasize = sizeof(buf);
if(fd->proto == DLT_LINUX_LAPD)
{
dataptr += sizeof(struct lapd_sll_hdr);
datasize -= sizeof(struct lapd_sll_hdr);
}
else
{
dataptr += sizeof(struct mtp2_phdr);
datasize -= sizeof(struct mtp2_phdr);
}
memset(buf, 0, sizeof(buf));
if(is_read)
{
res = read(fd->rfd, dataptr, datasize);
if(fd->rx_len > 0 && res == fd->rx_len && !memcmp(fd->rx_buf, dataptr, res) )
{
//skipping dup
return 0;
}
memcpy(fd->rx_buf, dataptr, res);
fd->rx_len = res;
}
else
{
res = read(fd->tfd, dataptr, datasize);
if(fd->tx_len > 0 && res == fd->tx_len && !memcmp(fd->tx_buf, dataptr, res) )
{
//skipping dup
return 0;
}
memcpy(fd->tx_buf, dataptr, res);
fd->tx_len = res;
}
gettimeofday(&hdr.ts, NULL);
if(res > 0)
{
if(fd->proto == DLT_LINUX_LAPD)
{
hdr.caplen = res+sizeof(struct lapd_sll_hdr)-2;
hdr.len = res+sizeof(struct lapd_sll_hdr)-2;
lapd->sll_pkttype = 3;
lapd->sll_hatype = 0;
lapd->sll_halen = res;
// lapd->sll_addr = ???
lapd->sll_protocol[0] = 0x00;
lapd->sll_protocol[1] = 0x30;
}
else
{
hdr.caplen = res+sizeof(struct mtp2_phdr);
hdr.len = res+sizeof(struct mtp2_phdr);
if(is_read)
{
mtp2->sent = 0;
mtp2->annex_a_used = 0;
}
else
{
mtp2->sent = 1;
mtp2->annex_a_used = 0;
}
mtp2->link_number = htons(fd->chan_id);
}
pcap_dump((u_char*)dump, &hdr, buf);
pcap_dump_flush(dump);
}
return 1;
}
void usage()
{
printf("Usage: dahdi_pcap [OPTIONS]\n");
printf("Capture packets from DAHDI channels to pcap file\n\n");
printf("Options:\n");
printf(" -p, --proto=[mtp2|lapd] The protocol to capture, default mtp2\n");
printf(" -c, --chan=<channels> Comma separated list of channels to capture from, max %d. Mandatory\n", MAX_CHAN);
printf(" -f, --file=<filename> The pcap file to capture to. Mandatory\n");
printf(" -h, --help Display this text\n");
}
int main(int argc, char **argv)
{
struct chan_fds chans[MAX_CHAN];
char *filename = NULL;
int num_chans = 0;
int max_fd = 0;
int proto = DLT_MTP2_WITH_PHDR;
int i;
int packetcount;
int c;
while (1) {
int option_index = 0;
static struct option long_options[] = {
{"proto", required_argument, 0, 'p'},
{"chan", required_argument, 0, 'c'},
{"file", required_argument, 0, 'f'},
{"help", 0, 0, 'h'},
{0, 0, 0, 0}
};
c = getopt_long(argc, argv, "p:c:f:?",
long_options, &option_index);
if (c == -1)
break;
switch (c) {
case 'p':
// Protocol
if(strcasecmp("LAPD", optarg)==0)
{
proto = DLT_LINUX_LAPD;
}
else if(argc > 0 && strcasecmp("MTP2", argv[1])==0)
{
proto = DLT_MTP2_WITH_PHDR;
}
break;
case 'c':
// TODO Should it be possible to override protocol per channel?
// Channels, comma separated list
while(optarg != NULL && num_chans < MAX_CHAN)
{
int chan = atoi(strsep(&optarg, ","));
chans[num_chans].tfd = make_mirror(DAHDI_TXMIRROR, chan);
chans[num_chans].rfd = make_mirror(DAHDI_RXMIRROR, chan);
chans[num_chans].chan_id = chan;
chans[num_chans].proto = proto;
if(chans[num_chans].tfd > max_fd)
{
max_fd = chans[num_chans].tfd;
}
if(chans[num_chans].rfd > max_fd)
{
max_fd = chans[num_chans].rfd;
}
num_chans++;
}
max_fd++;
break;
case 'f':
// File to capture to
filename=optarg;
break;
case 'h':
default:
// Usage
usage();
exit(0);
}
}
if((num_chans == 0) || (filename == NULL)) {
usage();
exit(0);
}
else
{
printf("Capturing protocol %s on channels ", (proto == DLT_MTP2_WITH_PHDR ? "mtp2":"lapd"));
for(i = 0; i < num_chans; i++)
{
printf("%d", chans[i].chan_id);
if(i<num_chans-1)
{
printf(", ");
}
}
printf(" to file %s\n", filename);
}
pcap_t * pcap = pcap_open_dead(chans[0].proto, BLOCK_SIZE*4);
pcap_dumper_t * dump = pcap_dump_open(pcap, filename);
packetcount=0;
while(1)
{
fd_set rd_set;
FD_ZERO(&rd_set);
for(i = 0; i < num_chans; i++)
{
FD_SET(chans[i].tfd, &rd_set);
FD_SET(chans[i].rfd, &rd_set);
}
select(max_fd, &rd_set, NULL, NULL, NULL);
for(i = 0; i < num_chans; i++)
{
if(FD_ISSET(chans[i].rfd, &rd_set))
{
packetcount += log_packet(&chans[i], 1, dump);
}
if(FD_ISSET(chans[i].tfd, &rd_set))
{
packetcount += log_packet(&chans[i], 0, dump);
}
}
printf("Packets captured: %d\r", packetcount);
fflush(stdout);
}
return 0;
}

View File

@@ -40,17 +40,32 @@
#define SIZE 8000
static int verbose;
static int pass = 0;
static float best = 0.0;
static float worst = 100.0;
static double total = 0.0;
static double delay_total = 0.0;
static double total_time = 0.0;
static double total_count = 0.0;
static inline float _fmin(float a, float b)
{
return (a < b) ? a : b;
}
static double calculate_accuracy(double count, double ms)
{
return ((count - _fmin(count, fabs(count - ms))) / count) * 100.0;
}
void hup_handler(int sig)
{
double accuracy = calculate_accuracy(total_count, total_time);
printf("\n--- Results after %d passes ---\n", pass);
printf("Best: %.3f -- Worst: %.3f -- Average: %f, Difference: %f\n",
best, worst, pass ? total/pass : 100.00, pass ? delay_total/pass : 100);
printf("Best: %.3f%% -- Worst: %.3f%% -- Average: %f%%\n",
best, worst, pass ? total/pass : 100.00);
printf("Cummulative Accuracy (not per pass): %0.3f\n",
pass ? accuracy : 0.0);
exit(0);
}
@@ -79,9 +94,7 @@ int main(int argc, char *argv[])
int count = 0;
int seconds = 0;
int curarg = 1;
int verbose = 0;
char buf[8192];
float score;
float ms;
struct timeval start, now;
fd = open("/dev/dahdi/pseudo", O_RDWR);
@@ -140,23 +153,23 @@ int main(int argc, char *argv[])
ms += (now.tv_sec - start.tv_sec) * 8000;
ms += (now.tv_usec - start.tv_usec) / 125.0;
if (count >= SIZE) {
double percent = 100.0 * (count - ms) / count;
const double percent = calculate_accuracy(count, ms);
if (verbose) {
printf("\n%d samples in %0.3f system clock sample intervals (%.3f%%)",
count, ms, 100 - percent);
count, ms, percent);
} else if (pass > 0 && (pass % 8) == 0) {
printf("\n");
}
score = 100.0 - fabs(percent);
if (score > best)
best = score;
if (score < worst)
worst = score;
if (percent > best)
best = percent;
if (percent < worst)
worst = percent;
if (!verbose)
printf("%.3f%% ", score);
total += score;
delay_total += 100 - percent;
printf("%.3f%% ", percent);
total += percent;
fflush(stdout);
total_count += count;
total_time += ms;
count = 0;
pass++;
}

View File

@@ -4,7 +4,7 @@
dahdi_cfg \- configures DAHDI kernel modules from /etc/dahdi/system.conf
.SH SYNOPSIS
.B dahdi_cfg [\-c \fICFG_FILE\fB] [\-s] [\-f] [\-t] [\-v [\-v ... ] ]
.B dahdi_cfg [\-c \fICFG_FILE\fB] [\-S\fINUM\fB [-S\fICHANS\fB]] [\-s] [\-f] [\-t] [\-v [\-v ... ] ]
.B dahdi_cfg \-h
@@ -26,11 +26,25 @@ Use an alternative configuration file instead of
.I /etc/dahdi/system.conf
.RE
.B \-C \fICHANNELS
.RS
Only apply changes to channels in the specified range. Only
applicable when \-S is in use.
.RE
.B \-s
.RS
Only shutdown spans.
.RE
.B \-S \fISPAN
.RS
Only apply changes to span no. \fISPAN\fR. For a digital span (with
a 'span=' line in the configuration file) this will do. For an analog
span you'll have to explicitly tell dahdi_cfg the range of channels,
using \-C .
.RE
.B \-f
.RS
Always configure every channel, even if it appears not to have changed.

62
doc/dahdi_maint.8 Normal file
View File

@@ -0,0 +1,62 @@
.TH "DAHDI_MAINT" "8" "9 Sep 2011" "" ""
.SH NAME
dahdi_maint \- Sets Dahdi spans into maintenance mode, e.g.: loopback
.SH SYNOPSIS
.B dahdi_maint \-s \fInum\fB [options]
.B dahdi_maint <\-h|\-\-help>
.SH DESCRIPTION
dahdi_maint uses the DAHDI_MAINT interface to set a Dahdi span (port
of a Dahdi adapter card) into loopback mode or similar maintenance mode.
.SH OPTIONS
.B \-s \-\-span \fInum\fR
.RS
The span number. Required.
.RE
.B \-l \-\-loopback <localhost|networkline|networkpayload|loopup|loopdown|off>
.RS
Loopback type. One of:
.IP localhost 4
loop back towards host
.IP networkline 4
network line loopback
.IP networkpayload 4
network payload loopback
.IP loopup 4
transmit loopup signal
.IP loopdown 4
transmit loopdown signal
.IP off 4
end loopback mode
.RE
.B \-i \-\-insert <fas|multi|crc|cas|prbs|bipolar>
.RS
Insert an error of a specific type
.RE
.SH EXAMPLES
Enable network line loopback on span 1:
dahdi_maint -s 1 --loopback networkline
Disable network line loopback on span 1:
dahdi_maint -s 1 --loopback off
.SH SEE ALSO
.PP
dahdi_tool(8), dahdi_cfg(8), asterisk(8).
.SH AUTHOR
.PP
This manual page was written by Tzafrir Cohen <tzafrir.cohen@xorcom.com>.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU General Public License, Version 2 any later
version published by the Free Software Foundation.

View File

@@ -1,37 +1,139 @@
.TH "DAHDI_MONITOR" "8" "16 June 2008" "" ""
.TH "DAHDI_MONITOR" "8" "9 Sep 2011" "" ""
.SH NAME
dahdi_monitor \- checks the rx/tx levels of DAHDI channels
dahdi_monitor \- checks the Rx/Tx levels of a DAHDI channels
.SH SYNOPSIS
.B dahdi_monitor \fIchannel number\fB [\-v] [\-f \fIFILE\fB]
.B dahdi_monitor \fInum\fB [\-v[v]]
.B dahdi_monitor \fInum\fB [\-o] [<\-f|\-F> \fIFILE\fB]
.B dahdi_monitor \fInum\fB [[<\-r|\-R> \fIFILE\fB]] [[<\-t|\-T> \fIFILE\fB]]
.SH DESCRIPTION
dahdi_monitor monitors a DAHDI channel. It gives you a visual
representation of the sound strengths and makes it easy to see if
the received or transmitted signals are too high or out of
balance
dahdi_monitor monitors a Dahdi channel. It can record the output to a
file, play it to the speaker, or visualize the audio levels on the
terminal.
Recorded audio files are by default raw signed linear PCM. If the file
name ends with ".wav", the recorded file will be a WAV file.
The visual display shows the current audio level at both the Rx
(audio Received by Asterisk) and
Tx (audio Transmitted by Asterisk)
To exit the program, press Ctrl-C.
.SH OPTIONS
The first (mandatory) parameter is the number of the channel
to monitor.
.B \-m
.RS
Multiple channels. Don't multiplex both Rx and Tx in a single channel.
Normally there's a different option that you need that implies it.
.RE
.B \-o
.RS
Plays the output to OSS (/dev/dsp). Requires -m not to be used.
.RE
.B \-v
.RS
Display visual audio levels.
Display Visual audio levels. With two v-s, Verbose mode is enabled, that
shows the actual levels as numbers. Note that this requires a terminal
wider than 80 columns to be properly displayed.
Implies -m.
.RE
.B \-f \fIFILE
.RS
Write output to FILE
Record the content of the channel (Tx + Rx) to a file.
.RE
Some extra, yet undocumented, options.
.B \-F \fIFILE
.RS
Record the content of the channel (Tx + Rx) before the echo canceler
to a file.
.RE
.B \-r \fIFILE
.RS
Record the content of the Rx channel to a file.
Implies -m.
.RE
.B \-R \fIFILE
.RS
Record the content of the R channel before the echo canceler to a file.
Implies -m.
.RE
.B \-s \fIFILE
.RS
Record the content of the Tx and Rx of the channel to a file.
.RE
.B \-S \fIFILE
.RS
Records a stereo of both Tx and Rx of the channel before the echo
canceler to a file.
.RE
.B \-t \fIFILE
.RS
Record the content of the Tx channel to a file.
Implies -m.
.RE
.B \-T \fIFILE
.RS
Record the content of the Tx channel before the echo canceler to a file.
Implies -m.
.RE
.SH EXAMPLES
Visualize audio levels on DAHDI channel 2:
dahdi_monitor 2 -v
Record channel 3 to a file:
dahdi_monitor 3 -f output.raw
This will create a raw PCM file (signed-linear, 8kHz, mono, 16 bits per
sample). Both the Tx and Rx will be multiplexed in a single channel.
It can be converted to a WAV file using e.g.:
sox -s -c1 -2 -r8000 output.raw output.wav
Record Tx and Rx of channel 5 to separate files. This time directly to
WAV files:
dahdi_monitor 5 -r output_rx.wav -t output_tx.wav
Record channel 8 to a stereo file (Tx and Rx on its two channels):
dahdi_monitor 8 -s output.raw
Converting it to a WAV file:
sox -s -c2 -2 -r8000 output.raw output.wav
.SH SEE ALSO
.PP
dahdi_tool(8), dahdi_cfg(8), asterisk(8).
dahdi_tool(8), dahdi_cfg(8).
.SH AUTHOR
.PP

View File

@@ -74,7 +74,7 @@ ASTRIBANK_OBJS = astribank_usb.o mpptalk.o $(XTALK_OBJS)
ABHEXLOAD_OBJS = astribank_hexload.o hexfile.o pic_loader.o $(ECHO_LOADER) $(ASTRIBANK_OBJS) $(OCT_HERE_OBJS)
ABTOOL_OBJS = astribank_tool.o $(ASTRIBANK_OBJS)
ABALLOW_OBJS = astribank_allow.o $(ASTRIBANK_OBJS)
ABALLOW_OBJS = astribank_allow.o astribank_license.o $(ASTRIBANK_OBJS)
TARGETS = .perlcheck astribank_is_starting
PROG_INSTALL = astribank_is_starting

View File

@@ -43,27 +43,42 @@ an FXO module of two ports.
Building and Installation
-------------------------
Apart from the standard DAHDI build requirements, you also need libusb
development headers to build the fpga_load firmware loader. This is
typically the package libusb-dev on Debian (and derivatives like Ubuntu)
or libusb-devel on RedHat (and derivatives like CentOS/Trixbox).
Apart from the standard DAHDI build requirements, you also need:
Patch for BRI
~~~~~~~~~~~~~
(As of DAHDI 2.2 this patch is no longer needed. Furthermore, it does
not apply. The same directory has a newer patch that applies. This
section is kept in the document for the time being for the benefit of
those with older versions)
* *libusb development headers* to build the fpga_load firmware loader.
This is typically the package libusb-dev on Debian (and derivatives
like Ubuntu) or libusb-devel on RedHat (and derivatives like
CentOS/Trixbox).
* *Echo Canceller Module firmware*: If you have an Astribank with an
echo canceller module, see the following section.
In order for the BRI module (xpd_bri.ko) to build, you still need an
external patch:
Follow the build instructions of DAHDI-linux and DAHDI-tools. But
Basically, in dahdi-linux run:
http://updates.xorcom.com/astribank/bristuff/dahdi_bri_dchan.diff[]
make
make install # as root
You need to apply it to the dahdi-linux tarball before building:
And later in dahdi-tools:
wget http://updates.xorcom.com/astribank/bristuff/dahdi_bri_dchan.diff
patch -p1 <dahdi_bri_dchan.diff
./configure
make
make install # as root
Echo Canceller Firmware
~~~~~~~~~~~~~~~~~~~~~~~
If you install from source, you should copy OCT6104E-256D.ima to the
source tree (before running make install:
wget http://updates.xorcom.com/astribank/hwec/OCT6104E-256D.ima
mv OCT6104E-256D.ima drivers/dahdi/xpp/firmwares/
Alternatively, if you have already installed DAHDI-linux (e.g. from a
binary package that does not include the firmware) you can just copy
it directly to the target directory, /usr/share/dahdi using:
cd /usr/share/dahdi
wget http://updates.xorcom.com/astribank/hwec/OCT6104E-256D.ima
Installation Scenarios
@@ -619,7 +634,13 @@ Asterisk Level Information
* the chan_dahdi.so file exists but it is not loaded. Try to load it manually:
asterisk -rx 'load module chan_dahdi.so'
asterisk -rx 'module load chan_dahdi.so'
* In some cases chan_dahdi failed to load properly and needs to be unloaded
before re-loading:
asterisk -rx 'module unload chan_dahdi.so'
asterisk -rx 'module load chan_dahdi.so'
- You see "pseudo" channel only. It means that you have not configured any
channels. If you have configured channels in chan_dahdi.conf, you may

View File

@@ -33,7 +33,7 @@ information used by Xorcom to generate/modify licensed capabilities.
Required. The device to read from/write to. This is
\fIbus_num\fR/\fIdevice_num\fR, where \fIbus_num\fR and \fIdevice_num\fR
are the first two numbers in the output of lsusb(8) or dahdi_hardware(8).
On older versions of this toolyou needed a complete path to the device,
On older versions of this tool you needed a complete path to the device,
which would be /dev/bus/usb/\fIbus_num\fR/\fIdevice_num\fR, or
/proc/bus/usb/\fIbus_num\fR/\fIdevice_num\fR.
.RE
@@ -48,6 +48,16 @@ Write capabilities to EEPROM, otherwise read capabilities
License filename (stdin/stdout if not specified)
.RE
.B \-m \fInum\fR
.RS
Choose the numeric code of license markers to generate.
This code select the type of \fIBEGIN\fR.../\fIEND\fR... strings
that delimit the license body.
Valid marker codes are listed with the \fB-h\fR option.
The default (and first) code is \fB1\fR. Zero is illegal value.
.RE
.B \-v
.RS
Increase verbosity. May be used multiple times.

View File

@@ -34,6 +34,7 @@
#include "mpp.h"
#include "mpptalk.h"
#include <debug.h>
#include "astribank_license.h"
static const char rcsid[] = "$Id$";
@@ -49,6 +50,8 @@ static void usage()
fprintf(stderr, "\t\t[-d mask] # Debug mask (0xFF for everything)\n");
fprintf(stderr, "\t\t[-w] # Write capabilities to EEPROM, otherwise read capabilities\n");
fprintf(stderr, "\t\t[-f filename] # License filename (stdin/stdout if not specified)\n\n");
fprintf(stderr, "\t\t[-m num] # Numeric code of License markers to generate\n");
license_markers_help("\t", stderr);
exit(1);
}
@@ -70,216 +73,6 @@ static int capabilities_burn(
return 0;
}
static int bin_to_file(void *buf, int len, FILE *f)
{
static int bytes_on_line;
unsigned char *p = buf;
if (buf == NULL) {
if (bytes_on_line != 0) {
if (fprintf(f, "\n") != 1)
return -1;
bytes_on_line = 0;
}
return 0;
}
int i;
for (i = 0; i < len; i++) {
if (fprintf(f, "%02x", *p++) != 2)
return -1;
bytes_on_line++;
if (bytes_on_line >= 16) {
if (fprintf(f, "\n") != 1)
return -1;
bytes_on_line = 0;
}
}
return 0;
}
static int write_to_file(struct eeprom_table *eeprom_table, struct capabilities *caps, struct capkey *key, FILE *f)
{
fprintf(f, "-----BEGIN XORCOM LICENSE BLOCK-----\n");
fprintf(f, "Version: 1.0\n");
fprintf(f, "Timestamp: %u\n", caps->timestamp);
fprintf(f, "Serial: %.*s\n", LABEL_SIZE, eeprom_table->label);
fprintf(f, "Capabilities.Port.FXS: %d\n", caps->ports_fxs);
fprintf(f, "Capabilities.Port.FXO: %d\n", caps->ports_fxo);
fprintf(f, "Capabilities.Port.BRI: %d\n", caps->ports_bri);
fprintf(f, "Capabilities.Port.PRI: %d\n", caps->ports_pri);
fprintf(f, "Capabilities.Port.ECHO: %d\n", caps->ports_echo);
fprintf(f, "Capabilities.Twinstar: %d\n", CAP_EXTRA_TWINSTAR(caps));
fprintf(f, "Data:\n");
bin_to_file(eeprom_table, sizeof(*eeprom_table), f);
bin_to_file(caps, sizeof(*caps), f);
bin_to_file(key, sizeof(*key), f);
bin_to_file(NULL, 0, f);
fprintf(f, "-----END XORCOM LICENSE BLOCK-----\n");
return 0;
}
/*
* Removes whitespace on both sizes of the string.
* Returns a pointer to the first non-space char. The string
* is modified in place to trim trailing whitespace.
* If the whole string is whitespace, returns NULL.
*/
char *trim(char *s)
{
int len = strlen(s);
while (len > 0 && isspace(s[len-1])) {
len--;
}
if (len == 0)
return NULL;
s[len] = '\0';
while (isspace(*s))
s++;
/* *s is not a space, since in this case we'd return NULL above */
return s;
}
int get_key_value(char *line, char **key, char **value)
{
char *p = strchr(line, ':');
if (p == NULL)
return -1;
*p = '\0';
*key = trim(line);
*value = trim(p + 1);
return 0;
}
static int hex_digit_to_int(char c)
{
if (c >= '0' && c <= '9')
return c - '0';
else if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
else
return -1;
}
static int str_to_bin(char *line, void *buf, int maxlen)
{
static int offset;
unsigned char *p = buf;
if (strlen(line) % 2 != 0)
return -1;
while (offset < maxlen && *line) {
uint8_t value;
char c = hex_digit_to_int(*line++);
if (c < 0 || *line == '\0')
return -1;
value = c << 4;
c = hex_digit_to_int(*line++);
if (c < 0)
return -1;
value |= c;
p[offset++] = value;
}
if (offset == maxlen && *line)
return -1;
return offset;
}
static int read_from_file(struct eeprom_table *eeprom_table, struct capabilities *caps, struct capkey *capkey, FILE *f)
{
char buf[256];
char *line, *key, *value;
int state = 0;
int lineno = 0;
struct table {
struct eeprom_table eeprom_table;
struct capabilities capabilities;
struct capkey capkey;
} PACKED table;
memset(&table, 0, sizeof(struct table));
/*
* states:
* 0: start - before BEGIN_LICENSE_BLOCK line. on BEGIN_LICENSE_BLOCK line goto 1.
* 1: read Version, goto 2. if not version line then error.
* 2: after BEGIN line. split line into key:value. if line is Data:, goto 3.
* 3: read binary data. if line is END_LICENSE_BLOCK goto 4.
* 4: END_LICENSE_BLOCK - ignore lines.
*/
while (fgets(buf, 256, f) != NULL) {
lineno++;
int len = strlen(buf);
if (len > 0 && buf[len-1] != '\n') {
ERR("Line %d: Line too long\n", lineno);
return -1;
}
line = trim(buf);
if (line == NULL) {
if (state > 0 && state < 4) {
ERR("Line %d: Empty line\n", lineno);
return -1;
}
else
continue;
}
switch (state) {
case 0:
if (strcmp(line, "-----BEGIN XORCOM LICENSE BLOCK-----") == 0)
state = 1;
else {
ERR("Line %d: Invalid license begin block\n", lineno);
return -1;
}
break;
case 1:
if (get_key_value(line, &key, &value) < 0) {
ERR("Line %d: Can't parse line\n", lineno);
return -1;
}
if (strcmp(key, "Version") == 0) {
if (strcmp(value, "1.0") == 0) {
state = 2;
} else {
ERR("Line %d: Unknown license file version '%s', need version '1.0'\n", lineno, value);
return -1;
}
} else {
ERR("Line %d: No license file version\n", lineno);
return -1;
}
break;
case 2:
if (get_key_value(line, &key, &value) < 0) {
ERR("Line %d: Can't parse line\n", lineno);
return -1;
}
if (strcmp(key, "Data") == 0) {
state = 3;
break;
}
break;
case 3:
if (strcmp(line, "-----END XORCOM LICENSE BLOCK-----") == 0) {
state = 4;
break;
}
if (str_to_bin(line, &table, sizeof(table)) < 0) {
ERR("Line %d: Error in data block\n", lineno);
return -1;
}
break;
case 4:
break;
}
}
if (state != 4) {
ERR("Invalid license file\n");
return -1;
}
memcpy(eeprom_table, &table.eeprom_table, sizeof(*eeprom_table));
memcpy(caps, &table.capabilities, sizeof(*caps));
memcpy(capkey, &table.capkey, sizeof(*capkey));
return 0;
}
int main(int argc, char *argv[])
{
char *devpath = NULL;
@@ -287,8 +80,9 @@ int main(int argc, char *argv[])
struct eeprom_table eeprom_table;
struct capabilities caps;
struct capkey key;
const char options[] = "vd:D:wf:";
const char options[] = "vd:D:wf:m:";
int do_write = 0;
unsigned int marker = LICENSE_MARKER_GENERIC;
FILE *file;
char *filename = NULL;
int ret;
@@ -317,6 +111,11 @@ int main(int argc, char *argv[])
case 'f':
filename = optarg;
break;
case 'm':
marker = strtoul(optarg, NULL, 0);
if (!license_marker_valid(marker))
usage();
break;
case 'h':
default:
ERR("Unknown option '%c'\n", c);
@@ -343,6 +142,7 @@ int main(int argc, char *argv[])
return 1;
}
if (do_write) {
unsigned int used_marker;
/* update capabilities based on input file */
file = stdin;
if (filename) {
@@ -352,7 +152,7 @@ int main(int argc, char *argv[])
return 1;
}
}
ret = read_from_file(&eeprom_table, &caps, &key, file);
ret = read_from_file(&eeprom_table, &caps, &key, &used_marker, file);
if (ret < 0) {
ERR("Failed to read capabilities from file: %d\n", ret);
return 1;
@@ -372,7 +172,7 @@ int main(int argc, char *argv[])
return 1;
}
}
ret = write_to_file(&eeprom_table, &caps, &key, file);
ret = write_to_file(&eeprom_table, &caps, &key, marker, file);
if (ret < 0) {
ERR("Failed to write capabilities to file: %d\n", ret);
return 1;

View File

@@ -1,19 +1,19 @@
.TH "ASTRIBANK_HEXLOAD" "8" "30 May 2011" "" ""
.SH NAME
astribank_tool \- Xorcom Astribank (xpp) firmware loader
astribank_hexload \- Xorcom Astribank (xpp) firmware loader
.SH SYNOPSIS
.B astribank_tool \-D \fIdevice-path\fR \-F [\fIoptions\fR] \fIhexfile\fR
.B astribank_hexload \-D \fIdevice-path\fR \-F [\fIoptions\fR] \fIhexfile\fR
.B astribank_tool \-D \fIdevice-path\fR \-p [\fIoptions\fR] \fIhexfile1 .. hexfile4\fR
.B astribank_hexload \-D \fIdevice-path\fR \-p [\fIoptions\fR] \fIhexfile1 .. hexfile4\fR
.B astribank_tool \-D \fIdevice-path\fR \-O [-A] [\fIoptions\fR] \fIimagefile\fR
.B astribank_hexload \-D \fIdevice-path\fR \-O [-A] [\fIoptions\fR] \fIimagefile\fR
.B astribank_tool \-D \fIdevice-path\fR \-o [\fIoptions\fR]
.B astribank_hexload \-D \fIdevice-path\fR \-o [\fIoptions\fR]
.B astribank_tool \-D \fIdevice-path\fR \-E [\fIoptions\fR] \fIhexfile\fR
.B astribank_hexload \-D \fIdevice-path\fR \-E [\fIoptions\fR] \fIhexfile\fR
.B astribank_tool \-h
.B astribank_hexload \-h
.SH DESCRIPTION
.B astribank_hexload
@@ -31,7 +31,7 @@ firmware. It is normally run by the script xpp_fxloader.
Required. The device to read from/write to. This is
\fIbus_num\fR/\fIdevice_num\fR, where \fIbus_num\fR and \fIdevice_num\fR
are the first two numbers in the output of lsusb(8) or dahdi_hardware(8).
On older versions of this toolyou needed a complete path to the device,
On older versions of this tool you needed a complete path to the device,
which would be /dev/bus/usb/\fIbus_num\fR/\fIdevice_num\fR, or
/proc/bus/usb/\fIbus_num\fR/\fIdevice_num\fR.
.RE

View File

@@ -24,6 +24,7 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <errno.h>
#include <assert.h>
#include <arpa/inet.h>
@@ -36,7 +37,7 @@
#include "../autoconfig.h"
#define DBG_MASK 0x80
#define MAX_HEX_LINES 10000
#define MAX_HEX_LINES 64000
#define HAVE_OCTASIC 1
static char *progname;
@@ -81,15 +82,27 @@ int handle_hexline(struct astribank_device *astribank, struct hexline *hexline)
return 0;
}
void print_parse_errors(int level, const char *msg, ...)
{
va_list ap;
if (verbose > level) {
va_start (ap, msg);
vfprintf (stderr, msg, ap);
va_end (ap);
}
}
static int load_hexfile(struct astribank_device *astribank, const char *hexfile, enum dev_dest dest)
{
struct hexdata *hexdata = NULL;
int finished = 0;
int ret;
int i;
unsigned i;
char star[] = "+\\+|+/+-";
const char *devstr;
parse_hexfile_set_reporting(print_parse_errors);
if((hexdata = parse_hexfile(hexfile, MAX_HEX_LINES)) == NULL) {
perror(hexfile);
return -errno;
@@ -100,13 +113,6 @@ static int load_hexfile(struct astribank_device *astribank, const char *hexfile,
xusb_serial(astribank->xusb),
dev_dest2str(dest),
hexdata->fname, hexdata->version_info);
#if 0
FILE *fp;
if((fp = fopen("fpga_dump_new.txt", "w")) == NULL) {
perror("dump");
exit(1);
}
#endif
if((ret = mpp_send_start(astribank, dest, hexdata->version_info)) < 0) {
ERR("%s: Failed hexfile send start: %d\n", devstr, ret);
return ret;

View File

@@ -68,7 +68,34 @@ NUM_WANTED=`clean_lines | sed '/^$/d' | wc -l`
NUM_GOOD=`matched_devices | wc -l`
LOCK="/var/lock/twinstar_startup"
# Wait until udev finished processing our requests
# so we know the device files were actually created
# before trying dahdi_cfg et-al.
wait_for_udev() {
UDEV_SETTLE_MAX_TIME=10
echo "Waiting for udev to settle down..."
if [ -x /sbin/udevsettle ]; then
# Old system, stand-alone udevsettle command
time /sbin/udevsettle --timeout="$UDEV_SETTLE_MAX_TIME"
elif [ -x /sbin/udevadm ]; then
# Assume modern system, udevadm has settle parameter
if ! time /sbin/udevadm settle --timeout="$UDEV_SETTLE_MAX_TIME"
then
echo "udevadm failed ($?)."
echo "Fallback to sleep $UDEV_SETTLE_MAX_TIME seconds."
sleep "$UDEV_SETTLE_MAX_TIME"
fi
else
echo "No udevsettle/udevadm."
echo "Fallback to sleep $UDEV_SETTLE_MAX_TIME seconds."
sleep "$UDEV_SETTLE_MAX_TIME"
fi
sleep 1 # Wait a bit more (races)
}
start_dahdi() {
wait_for_udev
script=/etc/init.d/dahdi
echo "Starting $script."
"$script" start | logger -i -t "$script"

340
xpp/astribank_license.c Normal file
View File

@@ -0,0 +1,340 @@
/*
* Written by Oron Peled <oron@actcom.co.il>
* Copyright (C) 2012, Xorcom
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <errno.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <debug.h>
#include "astribank_license.h"
#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
static const struct boundary {
const char *name;
const char *markers[2];
} boundaries[] = {
[LICENSE_MARKER_NONE] = { /* Skip 0 */
},
[LICENSE_MARKER_XORCOM] = {
"Xorcom",
{
"-----BEGIN XORCOM LICENSE BLOCK-----",
"-----END XORCOM LICENSE BLOCK-----",
},
},
[LICENSE_MARKER_GENERIC] = {
"Generic",
{
"-----BEGIN TELEPHONY DEVICE LICENSE BLOCK-----",
"-----END TELEPHONY DEVICE LICENSE BLOCK-----",
}
},
};
void license_markers_help(const char *prefix, FILE *fp)
{
int i;
fprintf(fp, "%sValid license markers:\n", prefix);
for (i = LICENSE_MARKER_NONE + 1; i < ARRAY_SIZE(boundaries); i++) {
const struct boundary *b = &boundaries[i];
if (b->markers[0] != 0)
fprintf(fp, "%s\t%d - %s\n", prefix, i, b->name);
}
}
int license_marker_valid(unsigned int which)
{
if (which >= ARRAY_SIZE(boundaries))
return 0;
if (boundaries[which].markers[0] == NULL)
return 0;
return 1;
}
static const char *marker_string(unsigned int which, int end_marker)
{
int selector = (end_marker) ? 1 : 0;
if (license_marker_valid(which)) {
return boundaries[which].markers[selector];
}
ERR("gen_marker: invalid marker %d\n", which);
return NULL;
}
static int marker_find(const char *str, int end_marker)
{
int selector = (end_marker) ? 1 : 0;
int i;
for (i = LICENSE_MARKER_NONE + 1; i < ARRAY_SIZE(boundaries); i++) {
const struct boundary *b = &boundaries[i];
const char *marker_str = b->markers[selector];
#if 0
DBG("marker_find(%s,%d)[%d]: %s\n",
str, end_marker, i, marker_str);
#endif
if (!marker_str)
continue;
if (strcmp(str, marker_str) == 0)
return i;
}
return 0;
}
static int bin_to_file(void *buf, int len, FILE *f)
{
static int bytes_on_line;
unsigned char *p = buf;
if (buf == NULL) {
if (bytes_on_line != 0) {
if (fprintf(f, "\n") != 1)
return -1;
bytes_on_line = 0;
}
return 0;
}
int i;
for (i = 0; i < len; i++) {
if (fprintf(f, "%02x", *p++) != 2)
return -1;
bytes_on_line++;
if (bytes_on_line >= 16) {
if (fprintf(f, "\n") != 1)
return -1;
bytes_on_line = 0;
}
}
return 0;
}
int write_to_file(
struct eeprom_table *eeprom_table,
struct capabilities *caps,
struct capkey *key,
unsigned int marker,
FILE *f)
{
fprintf(f, "%s\n", marker_string(marker, 0));
fprintf(f, "Version: 1.0\n");
fprintf(f, "Timestamp: %u\n", caps->timestamp);
fprintf(f, "Serial: %.*s\n", LABEL_SIZE, eeprom_table->label);
fprintf(f, "Capabilities.Port.FXS: %d\n", caps->ports_fxs);
fprintf(f, "Capabilities.Port.FXO: %d\n", caps->ports_fxo);
fprintf(f, "Capabilities.Port.BRI: %d\n", caps->ports_bri);
fprintf(f, "Capabilities.Port.PRI: %d\n", caps->ports_pri);
fprintf(f, "Capabilities.Port.ECHO: %d\n", caps->ports_echo);
fprintf(f, "Capabilities.Twinstar: %d\n", CAP_EXTRA_TWINSTAR(caps));
fprintf(f, "Data:\n");
bin_to_file(eeprom_table, sizeof(*eeprom_table), f);
bin_to_file(caps, sizeof(*caps), f);
bin_to_file(key, sizeof(*key), f);
bin_to_file(NULL, 0, f);
fprintf(f, "%s\n", marker_string(marker, 1));
return 0;
}
/*
* Removes whitespace on both sizes of the string.
* Returns a pointer to the first non-space char. The string
* is modified in place to trim trailing whitespace.
* If the whole string is whitespace, returns NULL.
*/
static char *trim(char *s)
{
int len = strlen(s);
while (len > 0 && isspace(s[len-1])) {
len--;
}
if (len == 0)
return NULL;
s[len] = '\0';
while (isspace(*s))
s++;
/* *s is not a space, since in this case we'd return NULL above */
return s;
}
static int get_key_value(char *line, char **key, char **value)
{
char *p = strchr(line, ':');
if (p == NULL)
return -1;
*p = '\0';
*key = trim(line);
*value = trim(p + 1);
return 0;
}
static int hex_digit_to_int(char c)
{
if (c >= '0' && c <= '9')
return c - '0';
else if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
else
return -1;
}
static int str_to_bin(char *line, void *buf, int maxlen)
{
static int offset;
unsigned char *p = buf;
if (strlen(line) % 2 != 0)
return -1;
while (offset < maxlen && *line) {
uint8_t value;
char c = hex_digit_to_int(*line++);
if (c < 0 || *line == '\0')
return -1;
value = c << 4;
c = hex_digit_to_int(*line++);
if (c < 0)
return -1;
value |= c;
p[offset++] = value;
}
if (offset == maxlen && *line)
return -1;
return offset;
}
int read_from_file(
struct eeprom_table *eeprom_table,
struct capabilities *caps,
struct capkey *capkey,
unsigned int *used_marker,
FILE *f)
{
char buf[256];
char *line, *key, *value;
int lineno = 0;
unsigned int license_marker_begin = 0;
unsigned int license_marker_end;
struct table {
struct eeprom_table eeprom_table;
struct capabilities capabilities;
struct capkey capkey;
} PACKED table;
enum PARSE_STATES {
STATE_BEFORE_LICENSE = 0,
STATE_EXPECT_VERSION = 1,
STATE_EXPECT_DATA = 2,
STATE_READ_DATA = 3,
STATE_AFTER_LICENSE = 4,
} state = STATE_BEFORE_LICENSE;
memset(&table, 0, sizeof(struct table));
/*
* states:
* 0: start - before BEGIN_LICENSE_BLOCK line. on BEGIN_LICENSE_BLOCK line goto 1.
* 1: read Version, goto 2. if not version line then error.
* 2: after BEGIN line. split line into key:value. if line is Data:, goto 3.
* 3: read binary data. if line is END_LICENSE_BLOCK goto 4.
* 4: END_LICENSE_BLOCK - ignore lines.
*/
while (fgets(buf, 256, f) != NULL) {
lineno++;
int len = strlen(buf);
if (len > 0 && buf[len-1] != '\n') {
ERR("Line %d: Line too long\n", lineno);
return -1;
}
line = trim(buf);
if (line == NULL) {
if (state > STATE_BEFORE_LICENSE && state < STATE_AFTER_LICENSE) {
ERR("Line %d: Empty line\n", lineno);
return -1;
}
else
continue;
}
switch (state) {
case STATE_BEFORE_LICENSE:
license_marker_begin = marker_find(line, 0);
if (license_marker_begin)
state = STATE_EXPECT_VERSION;
else {
ERR("Line %d: Invalid license begin block\n", lineno);
return -1;
}
break;
case STATE_EXPECT_VERSION:
if (get_key_value(line, &key, &value) < 0) {
ERR("Line %d: Can't parse line\n", lineno);
return -1;
}
if (strcmp(key, "Version") == 0) {
if (strcmp(value, "1.0") == 0) {
state = STATE_EXPECT_DATA;
} else {
ERR("Line %d: Unknown license file version '%s', need version '1.0'\n", lineno, value);
return -1;
}
} else {
ERR("Line %d: No license file version\n", lineno);
return -1;
}
break;
case STATE_EXPECT_DATA:
if (get_key_value(line, &key, &value) < 0) {
ERR("Line %d: Can't parse line\n", lineno);
return -1;
}
if (strcmp(key, "Data") == 0) {
state = STATE_READ_DATA;
break;
}
break;
case STATE_READ_DATA:
license_marker_end = marker_find(line, 1);
if (license_marker_end) {
if (license_marker_end != license_marker_begin) {
ERR("Line %d: End marker != Begin marker\n", lineno);
return -1;
}
state = STATE_AFTER_LICENSE;
break;
}
if (str_to_bin(line, &table, sizeof(table)) < 0) {
ERR("Line %d: Error in data block\n", lineno);
return -1;
}
break;
case STATE_AFTER_LICENSE:
break;
}
}
if (state != STATE_AFTER_LICENSE) {
ERR("Invalid license file\n");
return -1;
}
memcpy(eeprom_table, &table.eeprom_table, sizeof(*eeprom_table));
memcpy(caps, &table.capabilities, sizeof(*caps));
memcpy(capkey, &table.capkey, sizeof(*capkey));
return 0;
}

29
xpp/astribank_license.h Normal file
View File

@@ -0,0 +1,29 @@
#ifndef ASTRIBANK_ALLOW_H
#define ASTRIBANK_ALLOW_H
#include "mpp.h"
enum license_markers {
LICENSE_MARKER_NONE = 0,
LICENSE_MARKER_XORCOM = 1,
LICENSE_MARKER_GENERIC = 2,
};
int license_marker_valid(unsigned int which);
void license_markers_help(const char *prefix, FILE *fp);
int write_to_file(
struct eeprom_table *eeprom_table,
struct capabilities *caps,
struct capkey *key,
unsigned int marker,
FILE *f);
int read_from_file(
struct eeprom_table *eeprom_table,
struct capabilities *caps,
struct capkey *capkey,
unsigned int *used_marker,
FILE *f);
#endif /* ASTRIBANK_ALLOW_H */

View File

@@ -20,7 +20,7 @@ to the \-D command line option).
Required. The device to read from/write to. This is
\fIbus_num\fR/\fIdevice_num\fR, where \fIbus_num\fR and \fIdevice_num\fR
are the first two numbers in the output of lsusb(8) or dahdi_hardware(8).
On older versions of this toolyou needed a complete path to the device,
On older versions of this tool you needed a complete path to the device,
which would be /dev/bus/usb/\fIbus_num\fR/\fIdevice_num\fR, or
/proc/bus/usb/\fIbus_num\fR/\fIdevice_num\fR.
.RE

View File

@@ -64,6 +64,8 @@ static const struct xusb_spec astribank_specs[] = {
TYPE_ENTRY("USB-MULTI", 0x1161, 2, 1, 2, MP_EP_OUT, MP_EP_IN),
TYPE_ENTRY("FPGA-MULTI", 0x1162, 2, 1, 2, MP_EP_OUT, MP_EP_IN),
TYPE_ENTRY("BURNED-MULTI", 0x1164, 2, 1, 2, MP_EP_OUT, MP_EP_IN),
TYPE_ENTRY("USB-BURN", 0x1112, 2, 1, 2, MP_EP_OUT, MP_EP_IN),
};
static const struct xusb_spec astribank_pic_specs[] = {

View File

@@ -98,4 +98,16 @@ int eeprom_fill(struct eeprom_table *eprm,
int astribank_has_twinstar(struct astribank_device *astribank);
int label_isvalid(const char *label);
#define AB_REPORT(report_type, astribank, fmt, ...) \
report_type("%s [%s]: " fmt, \
xusb_devpath((astribank)->xusb), \
xusb_serial((astribank)->xusb), \
## __VA_ARGS__)
#define AB_INFO(astribank, fmt, ...) \
AB_REPORT(INFO, astribank, fmt, ## __VA_ARGS__)
#define AB_ERR(astribank, fmt, ...) \
AB_REPORT(ERR, astribank, fmt, ## __VA_ARGS__)
#endif /* ASTRIBANK_USB_H */

View File

@@ -111,7 +111,7 @@ __END__
=head1 NAME
dahdi_genconf - Generate configuration for dahdi channels.
dahdi_genconf - Generate configuration for Dahdi channels.
=head1 SYNOPSIS
@@ -126,7 +126,7 @@ It uses two information sources:
=item Hardware
The actual dahdi hardware is automatically detected on the host.
The actual Dahdi hardware is automatically detected on the host.
=item /etc/dahdi/genconf_parameters
@@ -137,7 +137,7 @@ variable.
=back
The dahdi_genconf script can generate various kinds of configuration files
as specificed by the generator arguments. Each generator is a perl classes
as specified by the generator arguments. Each generator is a perl class
in Dahdi::Config::Gen namespace. The generator names on the command line
are the class names in lowercase.
@@ -177,14 +177,14 @@ Currently, chandahdi is affected.
=item *
F<genconf_parameters> parsing is done via C<Dahdi::Config::Params>.
An object representing the parsed data is instanciated by:
An object representing the parsed data is instantiated by:
C<Dahdi::Config::Params-E<gt>new()>.
The C<item()> method of this object contains all the hard coded
defaults of the configuration directives.
=item *
A configuration object is instanciated by C<Dahdi::Config::Gen-E<gt>new($params)>.
A configuration object is instantiated by C<Dahdi::Config::Gen-E<gt>new($params)>.
The mapping of configuration directives into semantic configuration is
done in the constructor.

View File

@@ -72,7 +72,7 @@ sub show_disconnected(%) {
# FIXME: For verbose display we also need to see the XPP devices.
# If no spans are registered, this won't happen. A brute-force
# methood for making it happe:
# method for making it happen:
Dahdi::Xpp::xbuses if ($opts{'v'});
my @devices = Dahdi::Hardware->device_list;
@@ -139,7 +139,7 @@ dahdi_hardware [-v][-x]
=item -v
Verbose ouput - show spans used by each device etc. Currently only
Verbose output - show spans used by each device etc. Currently only
implemented for the Xorcom Astribank.
=item -x
@@ -150,7 +150,7 @@ Show disconnected Astribank unit, if any.
=head1 DESCRIPTION
Show all dahdi hardware devices. Devices are recognized according to
Show all Dahdi hardware devices. Devices are recognized according to
lists of PCI and USB IDs in Dahdi::Hardware::PCI.pm and
Dahdi::Hardware::USB.pm . For PCI it is possible to detect by
sub-vendor and sub-product ID as well.

View File

@@ -123,9 +123,7 @@ static void usb_buffer_showstatistics(struct astribank_device *astribank, struct
long usec;
usec = usb_buffer_usec(ub);
INFO("%s [%s]: Octasic statistics: packet_size=[%d, %ld, %d] packets=%d, bytes=%ld msec=%ld usec/packet=%d\n",
xusb_devpath(astribank->xusb),
xusb_serial(astribank->xusb),
AB_INFO(astribank, "Octasic statistics: packet_size=[%d, %ld, %d] packets=%d, bytes=%ld msec=%ld usec/packet=%ld\n",
ub->min_send,
ub->total_bytes / ub->num_sends,
ub->max_send,
@@ -144,7 +142,7 @@ static int usb_buffer_flush(struct astribank_device *astribank, struct usb_buffe
return 0;
ret = xusb_send(astribank->xusb, ub->data, ub->curr, TIMEOUT);
if(ret < 0) {
ERR("xusb_send failed: %d\n", ret);
AB_ERR(astribank, "xusb_send failed: %d\n", ret);
return ret;
}
DBG("%s: Written %d bytes\n", __func__, ret);
@@ -179,7 +177,7 @@ static int usb_buffer_append(struct astribank_device *astribank, struct usb_buff
char *buf, int len)
{
if (ub->curr + len >= ub->max_len) {
ERR("%s: buffer too small ub->curr=%d, len=%d, ub->max_len=%d\n",
AB_ERR(astribank, "%s: buffer too small ub->curr=%d, len=%d, ub->max_len=%d\n",
__func__, ub->curr, len, ub->max_len);
return -ENOMEM;
}
@@ -211,13 +209,13 @@ static int usb_buffer_send(struct astribank_device *astribank, struct usb_buffer
return ret;
ret = xusb_recv(astribank->xusb, buf, PACKET_SIZE, TIMEOUT);
if(ret <= 0) {
ERR("No USB packs to read: %s\n", strerror(-ret));
AB_ERR(astribank, "No USB packs to read: %s\n", strerror(-ret));
return -EINVAL;
}
DBG("%s: %d bytes recv\n", __func__, ret);
phead = (struct xpp_packet_header *)buf;
if(phead->header.op != SPI_RCV_XOP && phead->header.op != TST_RCV_XOP) {
ERR("Got unexpected reply OP=0x%02X\n", phead->header.op);
AB_ERR(astribank, "Got unexpected reply OP=0x%02X\n", phead->header.op);
dump_packet(LOG_ERR, DBG_MASK, "hexline[ERR]", buf, ret);
return -EINVAL;
}
@@ -260,7 +258,7 @@ int spi_send(struct astribank_device *astribank, uint16_t addr, uint16_t data, i
ret = usb_buffer_send(astribank, &usb_buffer, buf, pack_len, TIMEOUT, recv_answer);
if(ret < 0) {
ERR("usb_buffer_send failed: %d\n", ret);
AB_ERR(astribank, "usb_buffer_send failed: %d\n", ret);
return ret;
}
DBG("%s: Written %d bytes\n", __func__, ret);
@@ -287,15 +285,16 @@ int test_send(struct astribank_device *astribank)
ret = usb_buffer_send(astribank, &usb_buffer, buf, pack_len, TIMEOUT, 1);
if(ret < 0) {
ERR("usb_buffer_send failed: %d\n", ret);
AB_ERR(astribank, "usb_buffer_send failed: %d\n", ret);
return ret;
}
DBG("%s: Written %d bytes\n", __func__, ret);
return ret;
}
void echo_send_data(struct astribank_device *astribank, const unsigned int addr, const unsigned int data)
int echo_send_data(struct astribank_device *astribank, const unsigned int addr, const unsigned int data)
{
int ret;
/* DBG("SEND: %04X -> [%04X]\n", data, addr);
DBG("\t\t[%04X] <- %04X\n", 0x0008, (addr >> 20));
DBG("\t\t[%04X] <- %04X\n", 0x000A, (addr >> 4) & ((1 << 16) - 1));
@@ -304,25 +303,48 @@ void echo_send_data(struct astribank_device *astribank, const unsigned int addr,
*/
DBG("SND:\n");
spi_send(astribank, 0x0008, (addr >> 20) , 0, 0);
spi_send(astribank, 0x000A, (addr >> 4) & ((1 << 16) - 1) , 0, 0);
spi_send(astribank, 0x0004, data , 0, 0);
spi_send(astribank, 0x0000, (((addr >> 1) & 0x7) << 9) |
ret = spi_send(astribank, 0x0008, (addr >> 20) , 0, 0);
if (ret < 0)
goto failed;
ret = spi_send(astribank, 0x000A, (addr >> 4) & ((1 << 16) - 1) , 0, 0);
if (ret < 0)
goto failed;
ret = spi_send(astribank, 0x0004, data , 0, 0);
if (ret < 0)
goto failed;
ret = spi_send(astribank, 0x0000, (((addr >> 1) & 0x7) << 9) |
(1 << 8) | (3 << 12) | 1 , 0, 0);
if (ret < 0)
goto failed;
return cOCT6100_ERR_OK;
failed:
AB_ERR(astribank, "echo_send_data: spi_send failed (ret = %d)\n", ret);
return ret;
}
unsigned int echo_recv_data(struct astribank_device *astribank, const unsigned int addr)
int echo_recv_data(struct astribank_device *astribank, const unsigned int addr)
{
unsigned int data = 0x00;
unsigned int ret;
int ret;
DBG("RCV:\n");
spi_send(astribank, 0x0008, (addr >> 20) , 0, 0);
spi_send(astribank, 0x000A, (addr >> 4) & ((1 << 16) - 1) , 0, 0);
spi_send(astribank, 0x0000, (((addr >> 1) & 0x7) << 9) |
ret = spi_send(astribank, 0x0008, (addr >> 20) , 0, 0);
if (ret < 0)
goto failed;
ret = spi_send(astribank, 0x000A, (addr >> 4) & ((1 << 16) - 1) , 0, 0);
if (ret < 0)
goto failed;
ret = spi_send(astribank, 0x0000, (((addr >> 1) & 0x7) << 9) |
(1 << 8) | 1 , 0, 0);
if (ret < 0)
goto failed;
ret = spi_send(astribank, 0x0004, data , 1, 0);
if (ret < 0)
goto failed;
return ret;
failed:
AB_ERR(astribank, "echo_recv_data: spi_send failed (ret = %d)\n", ret);
return ret;
}
int load_file(char *filename, unsigned char **ppBuf, UINT32 *pLen)
@@ -418,9 +440,13 @@ UINT32 Oct6100UserDriverWriteApi(tPOCT6100_WRITE_PARAMS f_pWriteParams)
const unsigned int data = f_pWriteParams->usWriteData;
const struct echo_mod *echo_mod = (struct echo_mod *)(f_pWriteParams->pProcessContext);
struct astribank_device *astribank = echo_mod->astribank;
int ret;
echo_send_data(astribank, addr, data);
ret = echo_send_data(astribank, addr, data);
if (ret < 0) {
ERR("echo_send_data failed (ret = %d)\n", ret);
return cOCT6100_ERR_FATAL_DRIVER_WRITE_API;
}
return cOCT6100_ERR_OK;
}
@@ -434,9 +460,15 @@ UINT32 Oct6100UserDriverWriteSmearApi(tPOCT6100_WRITE_SMEAR_PARAMS f_pSmearParam
unsigned int i;
for (i = 0; i < len; i++) {
int ret;
addr = f_pSmearParams->ulWriteAddress + (i << 1);
data = f_pSmearParams->usWriteData;
echo_send_data(astribank, addr, data);
ret = echo_send_data(astribank, addr, data);
if (ret < 0) {
ERR("echo_send_data failed (ret = %d)\n", ret);
return cOCT6100_ERR_FATAL_DRIVER_WRITE_API;
}
}
return cOCT6100_ERR_OK;
}
@@ -451,9 +483,15 @@ UINT32 Oct6100UserDriverWriteBurstApi(tPOCT6100_WRITE_BURST_PARAMS f_pBurstParam
unsigned int i;
for (i = 0; i < len; i++) {
int ret;
addr = f_pBurstParams->ulWriteAddress + (i << 1);
data = f_pBurstParams->pusWriteData[i];
echo_send_data(astribank, addr, data);
ret = echo_send_data(astribank, addr, data);
if (ret < 0) {
ERR("echo_send_data failed (ret = %d)\n", ret);
return cOCT6100_ERR_FATAL_DRIVER_WRITE_API;
}
}
return cOCT6100_ERR_OK;
}
@@ -463,8 +501,14 @@ UINT32 Oct6100UserDriverReadApi(tPOCT6100_READ_PARAMS f_pReadParams)
const unsigned int addr = f_pReadParams->ulReadAddress;
const struct echo_mod *echo_mod = (struct echo_mod *)f_pReadParams->pProcessContext;
struct astribank_device *astribank = echo_mod->astribank;
int ret;
*f_pReadParams->pusReadData = echo_recv_data(astribank, addr);
ret = echo_recv_data(astribank, addr);
if (ret < 0) {
ERR("echo_recv_data failed (%d)\n", ret);
return cOCT6100_ERR_FATAL_DRIVER_READ_API;
}
*f_pReadParams->pusReadData = ret;
return cOCT6100_ERR_OK;
}
@@ -477,8 +521,15 @@ UINT32 Oct6100UserDriverReadBurstApi(tPOCT6100_READ_BURST_PARAMS f_pBurstParams)
unsigned int i;
for (i = 0;i < len; i++) {
unsigned int ret;
addr = f_pBurstParams->ulReadAddress + (i << 1);
f_pBurstParams->pusReadData[i] = echo_recv_data(astribank, addr);
ret = echo_recv_data(astribank, addr);
if (ret < 0) {
ERR("echo_recv_data failed (%d)\n", ret);
return cOCT6100_ERR_FATAL_DRIVER_READ_API;
}
f_pBurstParams->pusReadData[i] = ret;
}
return cOCT6100_ERR_OK;
}
@@ -486,7 +537,7 @@ UINT32 Oct6100UserDriverReadBurstApi(tPOCT6100_READ_BURST_PARAMS f_pBurstParams)
inline int get_ver(struct astribank_device *astribank)
{
return spi_send(astribank, 0, 0, 1, 1);
return spi_send(astribank, 0, 0, 1, 1);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@@ -511,18 +562,16 @@ UINT32 init_octasic(char *filename, struct astribank_device *astribank, int is_a
tOCT6100_CHANNEL_OPEN ChannelOpen;
UINT32 ulChanHndl;
test_send(astribank);
if (test_send(astribank) < 0)
return cOCT6100_ERR_FATAL;
cpld_ver = get_ver(astribank);
INFO("%s [%s]: Check EC_CPLD version: %d\n",
xusb_devpath(astribank->xusb),
xusb_serial(astribank->xusb),
cpld_ver);
AB_INFO(astribank, "Check EC_CPLD version: %d\n", cpld_ver);
if (cpld_ver < 0)
return cpld_ver;
return cOCT6100_ERR_FATAL;
else if (cpld_ver == EC_VER_TEST) {
INFO("+---------------------------------------------------------+\n");
INFO("| WARNING: TEST HARDWARE IS ON THE BOARD INSTEAD OF EC!!! |\n");
INFO("+---------------------------------------------------------+\n");
AB_INFO(astribank, "+---------------------------------------------------------+\n");
AB_INFO(astribank, "| WARNING: TEST HARDWARE IS ON THE BOARD INSTEAD OF EC!!! |\n");
AB_INFO(astribank, "+---------------------------------------------------------+\n");
return cOCT6100_ERR_OK;
}
@@ -537,10 +586,10 @@ UINT32 init_octasic(char *filename, struct astribank_device *astribank, int is_a
memset(&OpenChip, 0, sizeof(tOCT6100_CHIP_OPEN));
if (!(echo_mod = malloc(sizeof(struct echo_mod)))) {
ERR("cannot allocate memory for echo_mod\n");
return 1;
AB_ERR(astribank, "cannot allocate memory for echo_mod\n");
return cOCT6100_ERR_FATAL;
}
DBG("allocated mem for echo_mod\n");
DBG("allocated mem for echo_mod\n");
memset(echo_mod, 0, sizeof(struct echo_mod));
@@ -548,7 +597,7 @@ UINT32 init_octasic(char *filename, struct astribank_device *astribank, int is_a
ulResult = Oct6100ChipOpenDef( &OpenChip );
if (ulResult != cOCT6100_ERR_OK) {
ERR("Oct6100ChipOpenDef failed: result=%X\n", ulResult);
AB_ERR(astribank, "Oct6100ChipOpenDef failed: result=%X\n", ulResult);
return ulResult;
}
@@ -593,14 +642,14 @@ UINT32 init_octasic(char *filename, struct astribank_device *astribank, int is_a
&pbyImageData,
&ulImageByteSize );
if (pbyImageData == NULL || ulImageByteSize == 0){
ERR("Bad pbyImageData or ulImageByteSize\n");
return 1;
}
if ( ulResult != 0 ) {
ERR("Failed load_file %s (%08X)\n", filename, ulResult);
AB_ERR(astribank, "Failed load_file %s (%08X)\n", filename, ulResult);
return ulResult;
}
if (pbyImageData == NULL || ulImageByteSize == 0){
AB_ERR(astribank, "Bad pbyImageData or ulImageByteSize\n");
return cOCT6100_ERR_FATAL;
}
/* Assign the image file.*/
OpenChip.pbyImageFile = pbyImageData;
@@ -613,7 +662,7 @@ UINT32 init_octasic(char *filename, struct astribank_device *astribank, int is_a
ulResult = Oct6100GetInstanceSize(&OpenChip, &InstanceSize );
if (ulResult != cOCT6100_ERR_OK)
{
ERR("Oct6100GetInstanceSize failed (%08X)\n", ulResult);
AB_ERR(astribank, "Oct6100GetInstanceSize failed (%08X)\n", ulResult);
return ulResult;
}
@@ -622,14 +671,14 @@ UINT32 init_octasic(char *filename, struct astribank_device *astribank, int is_a
echo_mod->astribank = astribank;
if (!pApiInstance) {
ERR("Out of memory (can't allocate %d bytes)!\n", InstanceSize.ulApiInstanceSize);
return 1;
AB_ERR(astribank, "Out of memory (can't allocate %d bytes)!\n", InstanceSize.ulApiInstanceSize);
return cOCT6100_ERR_FATAL;
}
/* Perform actual open of chip */
ulResult = Oct6100ChipOpen(pApiInstance, &OpenChip);
if (ulResult != cOCT6100_ERR_OK) {
ERR("Oct6100ChipOpen failed: result=%X\n", ulResult);
AB_ERR(astribank, "Oct6100ChipOpen failed: result=%X\n", ulResult);
return ulResult;
}
DBG("%s: OCT6100 is open\n", __func__);
@@ -687,7 +736,7 @@ UINT32 init_octasic(char *filename, struct astribank_device *astribank, int is_a
ulResult = Oct6100ChannelOpen( pApiInstance,
&ChannelOpen );
if (ulResult != cOCT6100_ERR_OK) {
ERR("Found error on chan %d\n", nChan);
AB_ERR(astribank, "Found error on chan %d\n", nChan);
return ulResult;
}
}
@@ -736,7 +785,7 @@ UINT32 init_octasic(char *filename, struct astribank_device *astribank, int is_a
ulResult = Oct6100ChannelOpen( pApiInstance,
&ChannelOpen );
if (ulResult != cOCT6100_ERR_OK) {
ERR("Found error on chan %d\n", nChan);
AB_ERR(astribank, "Found error on chan %d\n", nChan);
return ulResult;
}
}
@@ -752,24 +801,21 @@ UINT32 init_octasic(char *filename, struct astribank_device *astribank, int is_a
int load_echo(struct astribank_device *astribank, char *filename, int is_alaw)
{
int iLen;
int ret;
unsigned char *pbyFileData = NULL;
const char *devstr;
UINT32 octasic_status;
devstr = xusb_devpath(astribank->xusb);
INFO("%s [%s]: Loading ECHOCAN Firmware: %s (%s)\n",
devstr, xusb_serial(astribank->xusb), filename,
(is_alaw) ? "alaw" : "ulaw");
AB_INFO(astribank, "Loading ECHOCAN Firmware: %s (%s)\n",
filename, (is_alaw) ? "alaw" : "ulaw");
usb_buffer_init(astribank, &usb_buffer);
ret = init_octasic(filename, astribank, is_alaw);
if (ret) {
ERR("ECHO %s burning failed (%08X)\n", filename, ret);
octasic_status = init_octasic(filename, astribank, is_alaw);
if (octasic_status != cOCT6100_ERR_OK) {
AB_ERR(astribank, "ECHO %s burning failed (%08X)\n",
filename, octasic_status);
return -ENODEV;
}
ret = usb_buffer_flush(astribank, &usb_buffer);
if (ret < 0) {
ERR("ECHO %s buffer flush failed (%d)\n", filename, ret);
AB_ERR(astribank, "ECHO %s buffer flush failed (%d)\n", filename, ret);
return -ENODEV;
}
usb_buffer_showstatistics(astribank, &usb_buffer);

View File

@@ -557,7 +557,6 @@ int match_usb_device_identity(const struct usb_config_descriptor *config_desc,
const struct astribank_type *my_usb_device_identify(const char devpath[], struct my_usb_device *mydev)
{
struct usb_device_descriptor *dev_desc;
struct usb_config_descriptor *config_desc;
int i;
@@ -570,7 +569,6 @@ const struct astribank_type *my_usb_device_identify(const char devpath[], struct
ERR("Bailing out\n");
return 0;
}
dev_desc = &mydev->dev->descriptor;
config_desc = mydev->dev->config;
for(i = 0; i < sizeof(astribank_types)/sizeof(astribank_types[0]); i++) {
if(match_usb_device_identity(config_desc, &astribank_types[i])) {
@@ -592,7 +590,6 @@ int my_usb_device_init(const char devpath[], struct my_usb_device *mydev, const
struct usb_interface *interface;
struct usb_interface_descriptor *iface_desc;
struct usb_endpoint_descriptor *endpoint;
int ret;
int i;
assert(mydev != NULL);
@@ -638,10 +635,10 @@ int my_usb_device_init(const char devpath[], struct my_usb_device *mydev, const
mydev->abtype = abtype;
mydev->my_ep_in = abtype->my_ep_in;
mydev->my_ep_out = abtype->my_ep_out;
ret = get_usb_string(mydev->iManufacturer, BUFSIZ, dev_desc->iManufacturer, mydev->handle);
ret = get_usb_string(mydev->iProduct, BUFSIZ, dev_desc->iProduct, mydev->handle);
ret = get_usb_string(mydev->iSerialNumber, BUFSIZ, dev_desc->iSerialNumber, mydev->handle);
ret = get_usb_string(mydev->iInterface, BUFSIZ, iface_desc->iInterface, mydev->handle);
get_usb_string(mydev->iManufacturer, BUFSIZ, dev_desc->iManufacturer, mydev->handle);
get_usb_string(mydev->iProduct, BUFSIZ, dev_desc->iProduct, mydev->handle);
get_usb_string(mydev->iSerialNumber, BUFSIZ, dev_desc->iSerialNumber, mydev->handle);
get_usb_string(mydev->iInterface, BUFSIZ, iface_desc->iInterface, mydev->handle);
INFO("ID=%04X:%04X Manufacturer=[%s] Product=[%s] SerialNumber=[%s] Interface=[%s]\n",
dev_desc->idVendor,
dev_desc->idProduct,

View File

@@ -48,7 +48,7 @@ __END__
=head1 NAME
lsdahdi - List all dahdi channels with their types and spans.
lsdahdi - List all Dahdi channels with their types and spans.
=head1 SYNOPSIS

View File

@@ -83,7 +83,7 @@ struct capkey {
} PACKED;
struct extrainfo {
char text[24];
char text[EXTRAINFO_SIZE];
} PACKED;
struct mpp_header {

View File

@@ -366,7 +366,17 @@ int mpp_extrainfo_get(struct astribank_device *astribank, struct extrainfo *info
}
assert(reply->header.op == MPP_EXTRAINFO_GET_REPLY);
if(info) {
int i;
memcpy(info, (void *)&CMD_FIELD(reply, MPP, EXTRAINFO_GET_REPLY, info), sizeof(*info));
/*
* clean non-printing characters
*/
for (i = sizeof(*info) - 1; i >= 0; i--) {
if (info->text[i] != (char)0xFF)
break;
info->text[i] = '\0';
}
}
free_command(reply);
return 0;
@@ -876,7 +886,11 @@ void show_astribank_status(struct astribank_device *astribank, FILE *fp)
void show_extrainfo(const struct extrainfo *extrainfo, FILE *fp)
{
fprintf(fp, "Extrainfo: : %s\n", (const char *)(extrainfo->text));
char buf[EXTRAINFO_SIZE + 1];
memcpy(buf, extrainfo->text, EXTRAINFO_SIZE);
buf[EXTRAINFO_SIZE] = '\0'; /* assure null termination */
fprintf(fp, "Extrainfo: : '%s'\n", buf);
}
int twinstar_show(struct astribank_device *astribank, FILE *fp)

View File

@@ -108,4 +108,6 @@ enum dev_dest {
DEST_EEPROM = 0x02,
};
#define EXTRAINFO_SIZE 24
#endif /* MPPTALK_DEFS_H */

View File

@@ -1500,7 +1500,6 @@ UINT32 Oct6100ApiReserveChannelResources(
IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen,
OUT tPOCT6100_API_ECHO_CHAN_INDEX f_pChanIndexConf )
{
tPOCT6100_SHARED_INFO pSharedInfo;
tPOCT6100_CHANNEL_OPEN_TDM pTdmConfig;
tPOCT6100_CHANNEL_OPEN_CODEC pCodecConfig;
@@ -1526,9 +1525,6 @@ UINT32 Oct6100ApiReserveChannelResources(
BOOL fExtToneChanEntry = FALSE;
BOOL fExtToneTsiEntry = FALSE;
BOOL fExtToneMixerEntry = FALSE;
/* Obtain local pointer to shared portion of instance. */
pSharedInfo = f_pApiInstance->pSharedInfo;
/* Obtain a local pointer to the configuration structures.*/
pTdmConfig = &f_pChannelOpen->TdmConfig;
@@ -1951,7 +1947,6 @@ UINT32 Oct6100ApiWriteChannelStructs(
UINT32 ulResult;
UINT32 ulDwordAddress;
UINT32 ulDwordData;
BOOL fConversionEnabled = FALSE;
BOOL fProgramAdpcmMem;
UINT32 ulCompType = 0;
UINT32 ulPcmLaw;
@@ -2036,62 +2031,50 @@ UINT32 Oct6100ApiWriteChannelStructs(
break;
case cOCT6100_G726_40KBPS:
ulCompType = 0x3;
fConversionEnabled = TRUE;
break;
case cOCT6100_G726_32KBPS:
ulCompType = 0x2;
fConversionEnabled = TRUE;
break;
case cOCT6100_G726_24KBPS:
ulCompType = 0x1;
fConversionEnabled = TRUE;
break;
case cOCT6100_G726_16KBPS:
ulCompType = 0x0;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_2C_ENCODED:
ulCompType = 0x4;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_3C_ENCODED:
ulCompType = 0x5;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_4C_ENCODED:
ulCompType = 0x6;
fConversionEnabled = TRUE;
break;
case cOCT6100_G726_ENCODED:
ulCompType = 0x9;
fConversionEnabled = TRUE;
break;
case cOCT6100_G711_G726_ENCODED:
ulCompType = 0xA;
fConversionEnabled = TRUE;
break;
case cOCT6100_G711_G727_2C_ENCODED:
ulCompType = 0xC;
fConversionEnabled = TRUE;
break;
case cOCT6100_G711_G727_3C_ENCODED:
ulCompType = 0xD;
fConversionEnabled = TRUE;
break;
case cOCT6100_G711_G727_4C_ENCODED:
ulCompType = 0xE;
fConversionEnabled = TRUE;
break;
default:
return cOCT6100_ERR_FATAL_D4;
@@ -2182,67 +2165,54 @@ UINT32 Oct6100ApiWriteChannelStructs(
break;
case cOCT6100_G726_40KBPS:
ulCompType = 0x3;
fConversionEnabled = TRUE;
break;
case cOCT6100_G726_32KBPS:
ulCompType = 0x2;
fConversionEnabled = TRUE;
break;
case cOCT6100_G726_24KBPS:
ulCompType = 0x1;
fConversionEnabled = TRUE;
break;
case cOCT6100_G726_16KBPS:
ulCompType = 0x0;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_40KBPS_4_1:
ulCompType = 0xD;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_40KBPS_3_2:
ulCompType = 0xA;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_40KBPS_2_3:
ulCompType = 0x6;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_32KBPS_4_0:
ulCompType = 0xE;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_32KBPS_3_1:
ulCompType = 0xB;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_32KBPS_2_2:
ulCompType = 0x7;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_24KBPS_3_0:
ulCompType = 0xC;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_24KBPS_2_1:
ulCompType = 0x8;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_16KBPS_2_0:
ulCompType = 0x9;
fConversionEnabled = TRUE;
break;
default:
@@ -3807,10 +3777,8 @@ UINT32 Oct6100ApiCheckChannelModify(
/* Check the TDM config.*/
if ( f_pChannelModify->fTdmConfigModified == TRUE )
{
tPOCT6100_CHANNEL_MODIFY_TDM pModifyTdm;
tPOCT6100_CHANNEL_OPEN_TDM pOpenTdm;
pModifyTdm = &f_pChannelModify->TdmConfig;
pOpenTdm = &f_pTempChanOpen->TdmConfig;
ulResult = Oct6100ApiCheckTdmConfig( f_pApiInstance,
@@ -4706,7 +4674,6 @@ UINT32 Oct6100ApiModifyChannelStructs(
tOCT6100_WRITE_PARAMS WriteParams;
tPOCT6100_API_CHANNEL_CODEC pApiCodecConf;
tPOCT6100_API_CHANNEL_TDM pApiTdmConf;
tPOCT6100_API_CHANNEL_VQE pApiVqeConf;
UINT32 ulResult;
UINT16 usReadData;
@@ -4717,8 +4684,6 @@ UINT32 Oct6100ApiModifyChannelStructs(
UINT32 ulToneConfIndex;
BOOL fClearPlayoutPointers = FALSE;
BOOL fConversionEnabled = FALSE;
/* Obtain local pointer to shared portion of instance. */
@@ -4740,7 +4705,6 @@ UINT32 Oct6100ApiModifyChannelStructs(
/* Obtain local pointer to the configuration structures of the tPOCT6100_API_CHANNEL structure. */
pApiCodecConf = &pChanEntry->CodecConfig;
pApiTdmConf = &pChanEntry->TdmConfig;
pApiVqeConf = &pChanEntry->VqeConfig;
/*=======================================================================*/
/* Init the RIN and SIN TSST index */
@@ -5090,62 +5054,50 @@ UINT32 Oct6100ApiModifyChannelStructs(
break;
case cOCT6100_G726_40KBPS:
ulCompType = 0x3;
fConversionEnabled = TRUE;
break;
case cOCT6100_G726_32KBPS:
ulCompType = 0x2;
fConversionEnabled = TRUE;
break;
case cOCT6100_G726_24KBPS:
ulCompType = 0x1;
fConversionEnabled = TRUE;
break;
case cOCT6100_G726_16KBPS:
ulCompType = 0x0;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_2C_ENCODED:
ulCompType = 0x4;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_3C_ENCODED:
ulCompType = 0x5;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_4C_ENCODED:
ulCompType = 0x6;
fConversionEnabled = TRUE;
break;
case cOCT6100_G726_ENCODED:
ulCompType = 0x9;
fConversionEnabled = TRUE;
break;
case cOCT6100_G711_G726_ENCODED:
ulCompType = 0xA;
fConversionEnabled = TRUE;
break;
case cOCT6100_G711_G727_2C_ENCODED:
ulCompType = 0xC;
fConversionEnabled = TRUE;
break;
case cOCT6100_G711_G727_3C_ENCODED:
ulCompType = 0xD;
fConversionEnabled = TRUE;
break;
case cOCT6100_G711_G727_4C_ENCODED:
ulCompType = 0xE;
fConversionEnabled = TRUE;
break;
default:
@@ -5262,67 +5214,54 @@ UINT32 Oct6100ApiModifyChannelStructs(
break;
case cOCT6100_G726_40KBPS:
ulCompType = 0x3;
fConversionEnabled = TRUE;
break;
case cOCT6100_G726_32KBPS:
ulCompType = 0x2;
fConversionEnabled = TRUE;
break;
case cOCT6100_G726_24KBPS:
ulCompType = 0x1;
fConversionEnabled = TRUE;
break;
case cOCT6100_G726_16KBPS:
ulCompType = 0x0;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_40KBPS_4_1:
ulCompType = 0xD;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_40KBPS_3_2:
ulCompType = 0xA;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_40KBPS_2_3:
ulCompType = 0x6;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_32KBPS_4_0:
ulCompType = 0xE;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_32KBPS_3_1:
ulCompType = 0xB;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_32KBPS_2_2:
ulCompType = 0x7;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_24KBPS_3_0:
ulCompType = 0xC;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_24KBPS_2_1:
ulCompType = 0x8;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_16KBPS_2_0:
ulCompType = 0x9;
fConversionEnabled = TRUE;
break;
default:
@@ -8885,7 +8824,6 @@ UINT32 Oct6100ApiWriteVqeNlpMemory(
{
tPOCT6100_API_CHANNEL pChanEntry;
tPOCT6100_SHARED_INFO pSharedInfo;
tOCT6100_WRITE_PARAMS WriteParams;
tOCT6100_BUFFER_PLAYOUT_STOP BufferPlayoutStop;
UINT32 ulResult;
UINT32 ulTempData;
@@ -8899,10 +8837,6 @@ UINT32 Oct6100ApiWriteVqeNlpMemory(
pSharedInfo = f_pApiInstance->pSharedInfo;
WriteParams.pProcessContext = f_pApiInstance->pProcessContext;
WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId;
/* Obtain a pointer to the new buffer's list entry. */
mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usChanIndex );
@@ -9856,7 +9790,6 @@ UINT32 Oct6100ApiWriteVqeAfMemory(
{
tPOCT6100_API_CHANNEL pChanEntry;
tPOCT6100_SHARED_INFO pSharedInfo;
tOCT6100_WRITE_PARAMS WriteParams;
UINT32 ulResult;
UINT32 ulTempData;
UINT32 ulAfConfigBaseAddress;
@@ -9868,10 +9801,6 @@ UINT32 Oct6100ApiWriteVqeAfMemory(
pSharedInfo = f_pApiInstance->pSharedInfo;
WriteParams.pProcessContext = f_pApiInstance->pProcessContext;
WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId;
/* Obtain a pointer to the new buffer's list entry. */
mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usChanIndex );
@@ -12338,12 +12267,8 @@ UINT32 Oct6100ApiWriteDebugChanMemory(
IN UINT16 f_usRinRoutTsiIndex,
IN UINT16 f_usSinSoutTsiIndex )
{
tPOCT6100_SHARED_INFO pSharedInfo;
UINT32 ulResult;
/* Obtain pointer to local portion of the instance. */
pSharedInfo = f_pApiInstance->pSharedInfo;
/*==============================================================================*/
/* Write the VQE configuration of the debug channel. */

View File

@@ -3569,9 +3569,7 @@ UINT32 Oct6100ApiBootSdram(
tPOCT6100_SHARED_INFO pSharedInfo;
tPOCT6100_API_CHIP_CONFIG pChipConfig;
tOCT6100_WRITE_PARAMS WriteParams;
tOCT6100_READ_PARAMS ReadParams;
UINT32 ulResult;
UINT16 usReadData;
UINT16 usWriteData23E;
UINT16 usWriteData230;
UINT32 i;
@@ -3587,11 +3585,6 @@ UINT32 Oct6100ApiBootSdram(
WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId;
ReadParams.pProcessContext = f_pApiInstance->pProcessContext;
ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId;
ReadParams.pusReadData = &usReadData;
usWriteData23E = 0x0000;
usWriteData230 = 0x0000;
@@ -4995,7 +4988,6 @@ UINT32 Oct6100ApiRunEgo(
OUT PUINT32 f_aulEntry )
{
tPOCT6100_SHARED_INFO pSharedInfo;
tPOCT6100_API_CHIP_CONFIG pChipConfig;
tOCT6100_WRITE_PARAMS WriteParams;
tOCT6100_READ_PARAMS ReadParams;
UINT32 ulResult;
@@ -5008,9 +5000,6 @@ UINT32 Oct6100ApiRunEgo(
/* Get local pointer to shared portion of instance. */
pSharedInfo = f_pApiInstance->pSharedInfo;
/* Get local pointer to the chip configuration structure. */
pChipConfig = &f_pApiInstance->pSharedInfo->ChipConfig;
/* Set the process context and user chip ID parameters once and for all. */
WriteParams.pProcessContext = f_pApiInstance->pProcessContext;
@@ -5210,7 +5199,6 @@ UINT32 Oct6100ApiInitChannels(
tPOCT6100_SHARED_INFO pSharedInfo;
UINT32 i;
UINT32 ulResult;
tOCT6100_WRITE_BURST_PARAMS BurstParams;
tOCT6100_WRITE_PARAMS WriteParams;
tOCT6100_READ_PARAMS ReadParams;
UINT16 usReadData;
@@ -5220,7 +5208,6 @@ UINT32 Oct6100ApiInitChannels(
UINT32 ulFeatureBitOffset;
UINT32 ulFeatureFieldLength;
UINT32 ulMask;
UINT16 ausWriteData[ 4 ];
UINT16 usLoopCount = 0;
UINT16 usWriteData = 0;
UINT16 usMclkRead;
@@ -5235,11 +5222,6 @@ UINT32 Oct6100ApiInitChannels(
WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId;
BurstParams.pProcessContext = f_pApiInstance->pProcessContext;
BurstParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId;
BurstParams.pusWriteData = ausWriteData;
ReadParams.pProcessContext = f_pApiInstance->pProcessContext;
ReadParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId;

View File

@@ -2893,7 +2893,6 @@ UINT32 Oct6100ApiBridgeAddParticipantToChannel(
tPOCT6100_API_CHANNEL pSourceChanEntry;
tPOCT6100_API_CHANNEL pDestinationChanEntry;
tPOCT6100_API_FLEX_CONF_PARTICIPANT pSourceParticipant;
tPOCT6100_API_FLEX_CONF_PARTICIPANT pDestinationParticipant;
tPOCT6100_SHARED_INFO pSharedInfo;
@@ -2914,7 +2913,6 @@ UINT32 Oct6100ApiBridgeAddParticipantToChannel(
mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, f_usBridgeIndex );
mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pSourceChanEntry, f_usSourceChannelIndex );
mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( f_pApiInstance->pSharedInfo, pSourceParticipant, pSourceChanEntry->usFlexConfParticipantIndex );
mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pDestinationChanEntry, f_usDestinationChannelIndex );
mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( f_pApiInstance->pSharedInfo, pDestinationParticipant, pDestinationChanEntry->usFlexConfParticipantIndex );
@@ -5069,12 +5067,9 @@ UINT32 Oct6100ApiBridgeRemoveParticipantFromChannel(
tPOCT6100_API_MIXER_EVENT pTempEntry;
tPOCT6100_API_MIXER_EVENT pLoadTempEntry;
tPOCT6100_API_MIXER_EVENT pLastEventEntry;
tPOCT6100_API_MIXER_EVENT pLastLoadOrAccumulateEventEntry;
tPOCT6100_API_CHANNEL pSourceChanEntry;
tPOCT6100_API_CHANNEL pDestinationChanEntry;
tPOCT6100_API_FLEX_CONF_PARTICIPANT pSourceParticipant;
tPOCT6100_API_FLEX_CONF_PARTICIPANT pDestinationParticipant;
tPOCT6100_SHARED_INFO pSharedInfo;
@@ -5083,7 +5078,6 @@ UINT32 Oct6100ApiBridgeRemoveParticipantFromChannel(
UINT32 ulResult;
UINT32 ulLoopCount;
UINT16 usLastLoadEventIndex;
UINT16 usLoadOrAccumulateEventIndex;
UINT16 usTempEventIndex;
UINT16 usPreviousEventIndex;
@@ -5091,7 +5085,6 @@ UINT32 Oct6100ApiBridgeRemoveParticipantFromChannel(
UINT16 usReadData;
BOOL fLastEvent = FALSE;
BOOL fSoutCopyEvent = FALSE;
/* Obtain local pointer to shared portion of instance. */
pSharedInfo = f_pApiInstance->pSharedInfo;
@@ -5107,8 +5100,6 @@ UINT32 Oct6100ApiBridgeRemoveParticipantFromChannel(
mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, f_usBridgeIndex );
mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pSourceChanEntry, f_usSourceChannelIndex );
mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( f_pApiInstance->pSharedInfo, pSourceParticipant, pSourceChanEntry->usFlexConfParticipantIndex );
mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pDestinationChanEntry, f_usDestinationChannelIndex );
mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( f_pApiInstance->pSharedInfo, pDestinationParticipant, pDestinationChanEntry->usFlexConfParticipantIndex );
@@ -5127,8 +5118,6 @@ UINT32 Oct6100ApiBridgeRemoveParticipantFromChannel(
mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usTempEventIndex );
pLastEventEntry = pLoadEventEntry;
pLastLoadOrAccumulateEventEntry = pLoadEventEntry;
usLastLoadEventIndex = usTempEventIndex;
usLastEventIndex = usTempEventIndex;
while( pTempEntry->usEventType != cOCT6100_MIXER_CONTROL_MEM_SUB_STORE &&
@@ -5224,9 +5213,6 @@ UINT32 Oct6100ApiBridgeRemoveParticipantFromChannel(
}
}
pLastLoadOrAccumulateEventEntry = pTempEntry;
usLastLoadEventIndex = usTempEventIndex;
/* Go to the next entry into the list. */
usTempEventIndex = pTempEntry->usNextEventPtr;
mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usTempEventIndex );
@@ -5362,7 +5348,6 @@ UINT32 Oct6100ApiBridgeRemoveParticipantFromChannel(
if ( pTempEntry->usEventType == cOCT6100_MIXER_CONTROL_MEM_COPY )
{
/* No more previous bridges. */
fSoutCopyEvent = TRUE;
}
/* Now modify the previous last Store or Sub-Store or Head-Node event from another bridge/channel. */
@@ -7412,7 +7397,6 @@ UINT32 Oct6100ApiGetPrevLastSubStoreEvent(
IN UINT16 f_usBridgeFirstLoadEventPtr,
OUT PUINT16 f_pusLastSubStoreEventIndex )
{
tPOCT6100_API_CONF_BRIDGE pBridgeEntry;
tPOCT6100_API_MIXER_EVENT pTempMixerEntry;
UINT16 usNextEventPtr;
UINT16 usHeadEventPtr;
@@ -7421,9 +7405,6 @@ UINT32 Oct6100ApiGetPrevLastSubStoreEvent(
UINT16 usCurrentPtr;
UINT32 ulResult = cOCT6100_ERR_OK;
/* Get current entry to obtain the link to the previous entry.*/
mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, f_usBridgeIndex );
/* Since we have flexible bridges, we have to */
/* run down the list and check for the appropriate event. */

View File

@@ -798,7 +798,6 @@ UINT32 Oct6100ApiReadIntrptRegs(
tPOCT6100_API_CHIP_ERROR_STATS pErrorStats;
tPOCT6100_API_INTRPT_MANAGE pIntrptManage;
tOCT6100_READ_PARAMS ReadParams;
tOCT6100_WRITE_PARAMS WriteParams;
UINT32 ulResult;
UINT16 usReadData;
@@ -820,13 +819,6 @@ UINT32 Oct6100ApiReadIntrptRegs(
ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId;
ReadParams.pusReadData = &usReadData;
/* Set some parameters of write struct. */
WriteParams.pProcessContext = f_pApiInstance->pProcessContext;
WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId;
/* CPU registers. */
if ( (f_ulRegister210h & 0x00001) != 0 )
{
@@ -1296,7 +1288,6 @@ UINT32 Oct6100ApiWriteIeRegs(
{
tPOCT6100_API_INTRPT_MANAGE pIntrptManage;
tOCT6100_WRITE_PARAMS WriteParams;
tOCT6100_READ_PARAMS ReadParams;
UINT32 ulResult;
/* Get some local pointers. */
@@ -1307,12 +1298,6 @@ UINT32 Oct6100ApiWriteIeRegs(
WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId;
/* Set some parameters of read struct. */
ReadParams.pProcessContext = f_pApiInstance->pProcessContext;
ReadParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId;
/*==================================================================================*/
WriteParams.ulWriteAddress = 0x104;
WriteParams.usWriteData = 0x0000;

View File

@@ -175,12 +175,9 @@ UINT32 Oct6100ApiValidateTsst(
{
tPOCT6100_SHARED_INFO pSharedInfo;
tPOCT6100_API_CHIP_CONFIG pChipConfig;
PUINT32 pulTsstAlloc;
/* Obtain local pointer to shared portion of instance. */
pSharedInfo = f_pApiInstance->pSharedInfo;
mOCT6100_GET_TSST_ALLOC_PNT( f_pApiInstance->pSharedInfo, pulTsstAlloc );
/* Obtain local pointer to chip configuration. */
pChipConfig = &pSharedInfo->ChipConfig;

View File

@@ -84,14 +84,12 @@ $Octasic_Revision: 20 $
{ \
PVOID _pProcessContext; \
UINT32 _ulUserChipId; \
UINT32 _ulWriteAddress; \
UINT16 _usWriteData; \
UINT32 _ulWriteLength; \
\
/* Store the data that is to be passed to the user. */ \
_pProcessContext = SmearParams.pProcessContext; \
_ulUserChipId = SmearParams.ulUserChipId; \
_ulWriteAddress = SmearParams.ulWriteAddress; \
_usWriteData = SmearParams.usWriteData; \
_ulWriteLength = SmearParams.ulWriteLength; \
\

View File

@@ -168,7 +168,7 @@ sub gen_channel($$) {
die "missing context for chan #$num type $type" unless $context;
$callerid = ($type eq 'FXO')
? 'asreceived'
: sprintf "\"Channel %d\" <%04d>", $num, $exten;
: sprintf "\"Channel %d\" <%d>", $num, $exten;
if($type eq 'IN') {
$immediate = 'yes';
}
@@ -182,7 +182,7 @@ sub gen_channel($$) {
printf ";;; line=\"%d %s%s%s\"\n", $num, $chan->fqn, $signalling, $info;
printf "signalling=$sig\n";
printf "callerid=$callerid\n";
printf "mailbox=%04d\n", $exten unless $type eq 'FXO';
printf "mailbox=%d\n", $exten unless $type eq 'FXO';
if(defined $group) {
printf "group=$group\n";
}

View File

@@ -0,0 +1,116 @@
package Dahdi::Config::Gen::Freepbxdb;
# Written by Tzafrir Cohen <tzafrir.cohen@xorcom.com>
# Copyright (C) 2011, Xorcom
# This program is free software; you can redistribute and/or
# modify it under the same terms as Perl itself.
use strict;
use Socket;
use Dahdi::Config::Gen qw(is_true);
sub new($$$) {
my $pack = shift || die;
my $gconfig = shift || die;
my $genopts = shift || die;
my $self = {
GCONFIG => $gconfig,
GENOPTS => $genopts,
};
bless $self, $pack;
return $self;
}
sub gen_channel($$) {
my $self = shift || die;
my $chan = shift || die;
my $gconfig = $self->{GCONFIG};
my $type = $chan->type;
my $num = $chan->num;
die "channel $num type $type is not an analog channel\n" if $chan->span->is_digital();
my $exten = $gconfig->{'base_exten'} + $num;
my $callerid = sprintf "\"Channel %d\" <%04d>", $num, $exten;
my @cmds = ();
#push @cmds, "database put DEVICE/$exten default_user $exten";
#push @cmds, "database put DEVICE/$exten dial ZAP/$num";
push @cmds, "database put DEVICE/$exten dial DAHDI/$num";
#push @cmds, "database put DEVICE/$exten type fixed";
push @cmds, "database put DEVICE/$exten user $exten";
push @cmds, "database put AMPUSER/$exten device $exten";
push @cmds, "database put AMPUSER/$exten cidname $callerid";
return @cmds;
}
sub generate($) {
my $self = shift || die;
my $gconfig = $self->{GCONFIG};
my $genopts = $self->{GENOPTS};
#$gconfig->dump;
my $ast_sock = '/var/run/asterisk/asterisk.ctl';
my @spans = @_;
my @cmds = ();
warn "Empty configuration -- no spans\n" unless @spans;
print "Configuring FXSs for FreePBX\n" if $genopts->{verbose};
foreach my $span (@spans) {
next if $span->is_digital;
foreach my $chan ($span->chans()) {
next unless ($chan->type eq 'FXS');
push @cmds, $self->gen_channel($chan);
}
}
#open(CMDS,"|$command >/dev/null") or
socket(SOCK, PF_UNIX, SOCK_STREAM, 0) || die "socket: $!";
connect(SOCK, sockaddr_un($ast_sock)) ||
die "$0: Freepbxdb: Failed connecting to $ast_sock\n: $!";
foreach (@cmds) {
# Note: commands are NULL-terminated:
print SOCK "$_\0";
sleep 0.001;
}
close(SOCK) or
die "$0: Freepbxdb: Failed sending commands ($ast_sock): $!\n";
}
1;
__END__
=head1 NAME
freepbxdb - Generate astdb configuration required by FreePBX
=head1 SYNOPSIS
use Dahdi::Config::Gen::Freepbxdb;
my $cfg = new Dahdi::Config::Gen::Freepbxdb(\%global_config, \%genopts);
$cfg->generate(@span_list);
=head1 DESCRIPTION
Updates the Asterisk DB entries for FXS channels detected. Requires
Asterisk running.
The configuration generated here bypasses FreePBX's standard configuration
and allows using a simple dialplan snippet such as:
[from-internal-custom](+)
exten => _4XXX,1,Dial(DAHDI/${EXTEN:1})
This may come in handy in testing. At least until FreePBX will provide a
simple automated interface to do the same.
=head1 OPTIONS
None, so far.
=head1 FILES
=over
=item C</var/run/asterisk/asterisk.sock>
The socket to which commands are sent. FIXME: make this a parameter.
=back

View File

@@ -30,7 +30,7 @@ sub get_sorted_xbuses(@) {
my @sorted_xbuses;
foreach my $xbus (@xbuses) {
my $last_spanno;
foreach my $xpd ($xbus->xpds) {
foreach my $xpd (Dahdi::Xpp::Xpd::telephony_devs($xbus->xpds())) {
my $spanno = $xpd->spanno;
if(!$spanno) {
printf STDERR "%s: Is not registered. Skipping.\n", $xpd->fqn;

View File

@@ -41,6 +41,7 @@ my %pci_ids = (
'd161:0210/0003' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE210P (3rd Gen)' },
'd161:0205' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE205P ' },
'd161:0210' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE210P ' },
'd161:1820' => { DRIVER => 'wct4xxp', DESCRIPTION => 'Wildcard TE820 (5th Gen)' },
# from wctdm24xxp
'd161:2400' => { DRIVER => 'wctdm24xxp', DESCRIPTION => 'Wildcard TDM2400P' },
@@ -133,7 +134,7 @@ my %pci_ids = (
'0b0b:0105' => { DRIVER => 'r1t1', DESCRIPTION => 'Rhino R1T1' },
'0b0b:0205' => { DRIVER => 'r4fxo', DESCRIPTION => 'Rhino R14FXO' },
'0b0b:0206' => { DRIVER => 'rcbfx', DESCRIPTION => 'Rhino RCB4FXO 4-channel FXO analog telphony card' },
'0b0b:0305' => { DRIVER => 'r1t1', DESCRIPTION => 'Rhino R1T1' },
'0b0b:0305' => { DRIVER => 'rxt1', DESCRIPTION => 'Rhino R4T1' },
'0b0b:0405' => { DRIVER => 'rcbfx', DESCRIPTION => 'Rhino R8FXX' },
'0b0b:0406' => { DRIVER => 'rcbfx', DESCRIPTION => 'Rhino RCB8FXX 8-channel modular analog telphony card' },
'0b0b:0505' => { DRIVER => 'rcbfx', DESCRIPTION => 'Rhino R24FXX' },
@@ -203,7 +204,7 @@ sub scan_devices($) {
$pci_devs{$name}{DRIVER} = '';
}
while(</sys/bus/pci/drivers/*/[0-9]*>) {
while(<$Dahdi::sys_base/bus/pci/drivers/*/[0-9]*>) {
m,^(.*?)/([^/]+)/([^/]+)$,;
my $prefix = $1;
my $drvname = $2;

View File

@@ -34,6 +34,7 @@ my %usb_ids = (
'e4e4:1161' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-modular USB-firmware' },
'e4e4:1162' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-modular FPGA-firmware' },
'e4e4:1163' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-TwinStar monitor' },
'e4e4:1164' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-EEPROM burner' },
# Sangoma USB FXO:
'10c4:8461' => { DRIVER => 'wanpipe', DESCRIPTION => 'Sangoma WANPIPE USB-FXO Device' },
@@ -183,6 +184,7 @@ sub scan_devices($) {
my @lines = split(/\n/);
my ($tline) = grep(/^T/, @lines);
my ($pline) = grep(/^P/, @lines);
my ($dline) = grep(/^I/, @lines);
my ($sline) = grep(/^S:.*SerialNumber=/, @lines);
my ($busnum,$devnum) = ($tline =~ /Bus=(\w+)\W.*Dev#=\s*(\w+)\W/);
my $devname = sprintf("%03d/%03d", $busnum, $devnum);
@@ -193,6 +195,10 @@ sub scan_devices($) {
$serial = $1;
#$serial =~ s/[[:^print:]]/_/g;
}
my $loaded;
if ($dline =~ /Driver=(\w+)/) {
$loaded = $1;
}
my $model = $usb_ids{"$vendor:$product"};
next unless defined $model;
my $d = Dahdi::Hardware::USB->new(
@@ -203,6 +209,7 @@ sub scan_devices($) {
SERIAL => $serial,
DESCRIPTION => $model->{DESCRIPTION},
DRIVER => $model->{DRIVER},
LOADED => $loaded,
);
push(@devices, $d);
}

View File

@@ -131,7 +131,7 @@ my @bri_strings = (
'(?:quad|octo)BRI PCI ISDN Card.* \[(NT|TE)\]',
'octoBRI \[(NT|TE)\] ',
'HFC-S PCI A ISDN.* \[(NT|TE)\] ',
'(B4XXP) \(PCI\) Card', # Does not expose NT/TE type
'(B4XXP) \(PCI\) Card', # Use dahdi_scan to determine TE/NT mode
'(WCBRI)', # has selectable NT/TE modes via dahdi_cfg
);
@@ -144,7 +144,7 @@ my @pri_strings = (
'Wildcard TE120P', # wcte12xp
'Wildcard TE121', # wcte12xp
'Wildcard TE122', # wcte12xp
'T[24]XXP \(PCI\) Card ', # wct4xxp
'T[248]XXP \(PCI\) Card ', # wct4xxp
'R[24]T1 \(PCI\) Card', # rxt1
'Rhino R1T1 (E1)/PRA Card', # r1t1
'Rhino R1T1 (T1)/PRI Card', # r1t1
@@ -177,6 +177,28 @@ sub init_proto($$) {
$self->{TYPE} = "${proto}_$self->{TERMTYPE}";
}
sub get_digital_spantype {
my $span_no = shift;
my @lines = split /\n/, `dahdi_scan`;
my $found_span = 0;
foreach my $line (@lines) {
if (! $found_span) {
if ($line =~ m/\[$span_no\]/) {
$found_span = 1;
}
} else {
if ($line !~ m/^\[/) {
if ($line =~ m/digital-(TE|NT)/ ){
return $1;
}
} else {
$found_span = 0;
}
}
}
die "Cannot determine digital spantype";
}
sub new($$) {
my $pack = shift or die "Wasn't called as a class method\n";
my $proc_file = shift or die "Missing a proc file parameter\n";
@@ -191,10 +213,16 @@ sub new($$) {
$self->{IS_DIGITAL} = 0;
$self->{IS_BRI} = 0;
$self->{IS_PRI} = 0;
$self->{TERMTYPE} = "UNKNOWN";
foreach my $cardtype (@bri_strings) {
if($head =~ m/$cardtype/) {
my $termtype = $1;
$termtype = 'TE' if ( $1 eq 'B4XXP' or $1 eq 'WCBRI' );
if ($1 eq 'B4XXP') {
$termtype = get_digital_spantype($num);
}
if ($1 eq 'WCBRI') {
$termtype = 'TE';
}
$self->{IS_DIGITAL} = 1;
$self->{IS_BRI} = 1;
$self->{TERMTYPE} = $termtype;
@@ -230,6 +258,11 @@ sub new($$) {
last;
}
}
if (($self->is_soft_term_type == 0) and ($self->termtype eq "UNKNOWN")) {
$self->{IS_SOFT_TERM_TYPE} = 1;
}
($self->{NAME}, $self->{DESCRIPTION}) = (split(/\s+/, $head, 4))[2, 3];
$self->{IS_DAHDI_SYNC_MASTER} =
($self->{DESCRIPTION} =~ /\(MASTER\)/) ? 1 : 0;
@@ -368,7 +401,7 @@ SPEC:
#print STDERR "match: $match\n";
foreach my $pattern (@patlist) {
#print STDERR "testmatch: $pattern =~ $match\n";
if($pattern =~ $match) {
if($pattern =~ /^$match$/) {
#print STDERR "MATCH '$pattern' ~ '$match' termtype=$termtype\n";
$match_termtype = $termtype;
last SPEC;

View File

@@ -29,13 +29,53 @@ set -e
# For lab testing
mydir=`dirname $0`
PATH="${mydir}:${PATH}"
XPP_WAIT_AB_TIMEOUT=100
[ -r /etc/dahdi/init.conf ] && . /etc/dahdi/init.conf
ab_list() {
find /sys/devices -name idVendor 2>/dev/null | \
xargs grep -H 'e4e4' 2>/dev/null | \
sed -e 's/idVendor.*/idProduct/' | xargs grep -H '11[3456]' | \
sed 's,/[^/]*$,,' || :
}
ab_serial_nums() {
ab_list | \
sed 's,$,/serial,' | \
xargs grep -H '' 2>/dev/null | \
sed 's,.*/serial:,,' | \
sed 's/^$/NO-SERIAL/' | \
sort -u
}
detected_serial_nums() {
cat /sys/bus/astribanks/devices/*/transport/serial 2> /dev/null | \
sed 's/^$/NO-SERIAL/' | \
sort -u || :
}
calc_union() {
echo "$@" | tr -s ' ' '\n' | sort -u
}
detected_ab_list() {
# Only check /sys info (don't use /proc anymore).
ab=`find /sys/bus/astribanks/devices/xbus-*/ -name waitfor_xpds 2> /dev/null || :`
echo $ab
find /sys/bus/astribanks/devices/*/ -name waitfor_xpds 2> /dev/null || :
}
waitfor_ab_initialization() {
oldab=''
while
if ! ab=`detected_ab_list`; then
exit 1
fi
test "$oldab" != "$ab"
do
oldab="$ab"
cat $ab
#echo -n 1>&2 "_"
done
}
# Any hardware?
@@ -54,10 +94,25 @@ if ! astribank_is_starting; then
exit 0
fi
# Wait for driver and first device
serial_nums=`ab_serial_nums`
# Loop until detected (hopefully) all astribanks and they are initialized
echo -n 1>&2 "Astribanks detection "
tries=40
while [ ! -e "/sys/bus/astribanks/devices/xbus-00" ]
tries="$XPP_WAIT_AB_TIMEOUT"
last_detected=0
while
new_serial_nums=`ab_serial_nums`
detected_serial_nums=`detected_serial_nums`
curr_union=`calc_union $curr_union $serial_nums $new_serial_nums`
num_detected=`detected_ab_list | wc -l`
if [ "$num_detected" != "$last_detected" ]; then
# Visual feedback (number of detected AB so far)
echo -n 1>&2 "[$num_detected]"
last_detected="$num_detected"
waitfor_ab_initialization > /dev/null
fi
# Break only when we have something and it's stable
test "$curr_union" != "$detected_serial_nums" -o "$detected_serial_nums" = ''
do
if [ "$tries" -le 0 ]; then
echo 1>&2 "TIMEOUT"
@@ -66,21 +121,15 @@ do
echo -n 1>&2 "."
sleep 1
: $((tries-=1))
serial_nums="$new_serial_nums"
done
# Finished: Show a nice output
echo ""
cat /sys/bus/astribanks/devices/*/waitfor_xpds 2> /dev/null || :
# Wait for device to stabilize and XPD's to finish initalizations
echo 1>&2 "Astribanks initializing spans"
while
if ! ab=`ab_list`; then
exit 1
fi
test "$oldab" != "$ab"
do
oldab="$ab"
cat $ab
done
if [ "$XPP_HOTPLUG_DAHDI" = yes ]; then
if [ "$CALLED_FROM_ATRIBANK_HOOK" = '' ]; then
# Now we can wait until the hotplug run would remove the semaphore

View File

@@ -56,7 +56,7 @@ else
fi
debug() {
[ "$DEBUG" != "" ] && $LOGGER "$@"
[ "$DEBUG" != "" ] && echo >&2 "$@"
return 0
}
@@ -70,7 +70,6 @@ ASTRIBANK_TOOL=${ASTRIBANK_TOOL:-/usr/sbin/astribank_tool}
XPP_CONFIG="${XPP_CONFIG:-/etc/dahdi/xpp.conf}"
XPP_UDEV_SLEEP_TIME="${XPP_UDEV_SLEEP_TIME:-15}"
USB_FW="${USB_FW:-USB_FW.hex}"
USB_RECOV="${USB_RECOV:-USB_RECOV.hex}"
if [ -r "$DEFAULTS" ]; then
@@ -105,46 +104,168 @@ find_dev() {
run_fxload() {
sleep_if_race
fxload -t fx2 $* 2>&1 1>/dev/null | $LOGGER
fxload -t fx2 $* 2>&1 1>/dev/null
status=$PIPESTATUS
if [ $status != 0 ]; then
$LOGGER "fxload failed with status $status"
echo >&2 "fxload failed with status $status"
exit 55
fi
}
list_via_proc() {
cat /proc/bus/usb/devices | egrep '^P:|^T:' | sed \
-e '/^T:/s/ *Spd.*//' \
-e '/^T:/s, *Lev.*Dev#= *,\t,' \
-e '/^T:/s,Bus=,,' \
-e '/^P:/s,[A-Za-z]\+=,,g' \
-e '/^P:/s,\.,,g' | awk -vusb_prefix="$USB_PREFIX" '
/^T:/ {
bus=$2
dev=$3
}
/^P:/ {
vendor=$2
sub("0x", "", vendor);
prod=$3
sub("0x", "", product);
bcd=$4
printf("%4s/%4s/%d\t%s/%03d/%03d\n",
vendor, prod, bcd, usb_prefix, bus, dev);
}
'
}
list_via_sysfs() {
find /sys/bus/usb/devices -maxdepth 1 -mindepth 1 | \
egrep -v '/usb[0-9]|:' | while read dev; do
(
cat "$dev/idVendor"
cat "$dev/idProduct"
cat "$dev/bcdDevice"
echo "$dev" | sed \
-e 's,/sys/bus/usb/devices/,,' \
-e 's,-.*,,'
cat "$dev/devnum"
) | tr -s '\n' '\t'
echo ''
done | awk -vusb_prefix="$USB_PREFIX" '{
printf("%4s/%4s/%d\t%s/%03d/%03d\n",
$1, $2, $3, usb_prefix, $4, $5);
}'
}
list_via_lsusb() {
lsusb -v | awk -vusb_prefix="$USB_PREFIX" '
/^Bus/ {
sub(":", "", $4);
dev = sprintf("%s/%s/%s ", usb_prefix, $2, $4);
}
/idVendor/ {
id_vendor = $2
sub("0x", "", id_vendor);
}
/idProduct/ {
id_product = $2
sub("0x", "", id_product);
}
/bcdDevice/ {
bcd_device = $2
sub("^0*", "", bcd_device);
sub("[.]", "", bcd_device);
printf("%s/%s/%s\t%s\n",
id_vendor, id_product, bcd_device, dev);
}
'
}
list_devs() {
#echo >&2 "list_devs"
if [ "$#" -eq 0 ]; then
if [ -f /proc/bus/usb/devices ]; then
method='via_proc'
elif [ -d /sys/bus/usb/devices ]; then
method='via_sysfs'
else
method='via_lsusb'
fi
elif [ "$#" -eq 1 ]; then
method="$1"
else
echo >&2 "$0: unknown list_devs method='$method'"
exit 1
fi
case "$method" in
via_proc|via_sysfs|via_lsusb)
;;
*)
echo >&2 "$0: unknown list_devs method='$method'"
exit 1
;;
esac
list_$method | grep -v '^0000/0000/' | sort
}
filter_devs() {
id_str="$1"
#echo >&2 "filter_devs($id_str)"
list_devs | awk -vid_str="$id_str" '{ if ($1 ~ id_str) { print } }'
}
usb_firmware_device() {
id_str="$1"
devpath="$2"
case "$id_str" in
e4e4/11[3456]0/101|e4e4/1163/101)
fw="USB_FW.hex"
;;
e4e4/116[03]/201)
fw="USB_FW.201.hex"
;;
e4e4/*)
debug "No USB firmware for device $devpath ($id_str)"
return
;;
*)
return
;;
esac
fw_file="$FIRMWARE_DIR/$fw"
ver=$(awk '/\$Id:/ { print $4 }' $fw_file)
debug "USB Firmware $fw_file (Version=$ver) into $devpath"
run_fxload -D "$devpath" -I "$fw_file" || exit 1
}
run_astribank_hexload() {
debug "Running: $ASTRIBANK_HEXLOAD $*"
$ASTRIBANK_HEXLOAD "$@" | $LOGGER
$ASTRIBANK_HEXLOAD "$@"
status=$PIPESTATUS
if [ $status != 0 ]; then
$LOGGER "$ASTRIBANK_HEXLOAD failed with status $status"
echo >&2 "$ASTRIBANK_HEXLOAD failed with status $status"
exit 77
fi
}
run_astribank_tool() {
debug "Running: $ASTRIBANK_TOOL $*"
$ASTRIBANK_TOOL "$@" | $LOGGER
$ASTRIBANK_TOOL "$@"
status=$PIPESTATUS
if [ $status != 0 ]; then
$LOGGER "$ASTRIBANK_TOOL failed with status $status"
echo >&2 "$ASTRIBANK_TOOL failed with status $status"
exit 77
fi
}
load_usb_fw() {
v_id=$1
p_id=$2
fw=$3
devices=`find_dev $v_id $p_id`
for dev in $devices
do
ver=$(awk '/\$Id:/ { print $4 }' $FIRMWARE_DIR/$fw)
debug "USB Firmware $FIRMWARE_DIR/$fw (Version=$ver) into $dev"
run_fxload -D $dev -I $FIRMWARE_DIR/$fw || exit 1
done
usb_firmware_all_devices() {
devs=`list_devs`
echo "USB firmware"
echo "$devs" | while read id_str devpath
do
usb_firmware_device "$id_str" "$devpath"
done
wait_renumeration $numdevs 'e4e4/11[3456]1/*' "usb_firmware_all_devices"
}
load_fw_device() {
@@ -152,16 +273,18 @@ load_fw_device() {
fw="$2"
debug "FPGA loading $fw into $dev"
run_astribank_hexload -D "$dev" -F "$FIRMWARE_DIR/$fw"
if [ "$fw" = "FPGA_1161.hex" ]; then
case "$fw" in
FPGA_1161*.hex)
echo_file="$FIRMWARE_DIR/OCT6104E-256D.ima"
law=''
law_str='uLaw'
abtool_output=`$ASTRIBANK_TOOL -D "$dev" -Q 2>/dev/null`
card_type=`echo "$abtool_output" | grep '^CARD 4:' | cut -d= -f2 | cut -d. -f1`
if [ "$card_type" = '5' ]; then
abtool_output=`$ASTRIBANK_TOOL -D "$dev" -Q 2>&1`
ec_card_type=`echo "$abtool_output" | grep 'CARD 4' | sed -e 's/.*type=//' -e 's/\..*//'`
caps_num=`echo "$abtool_output" | grep 'ECHO ports' | sed -e 's/.*: *//'`
if [ "$ec_card_type" = '5' ]; then
debug "ECHO burning into $dev: $echo_file"
card_type_first=`echo "$abtool_output" | grep '^CARD 0:' | cut -d= -f2 | cut -d. -f1`
case "$card_type_first" in
card_type=`echo "$abtool_output" | grep 'CARD 0' | sed -e 's/.*type=//' -e 's/\..*//'`
case "$card_type" in
3) law="-A";;
4)
pri_protocol=''
@@ -182,88 +305,116 @@ load_fw_device() {
if [ "$caps_num" != '0' ]; then
run_astribank_hexload -D "$dev" -O $law "$echo_file"
else
$LOGGER "WARNING: ECHO burning was skipped (no capabilities)"
echo "WARNING: ECHO burning was skipped (no capabilities)"
fi
fi
pic_files=`echo "$FIRMWARE_DIR"/PIC_TYPE_[1-4].hex`
debug "PIC burning into $dev: $pic_files"
debug "PIC burning into $dev: begin $pic_files"
run_astribank_hexload -D "$dev" -p $pic_files
debug "PIC burning finished $pic_files"
fi
debug "PIC burning into $dev: end $pic_files"
;;
esac
# Do renumeration!
run_astribank_tool -D "$dev" -n > /dev/null
debug "Reenumeration done."
run_astribank_tool -D "$dev" -n > /dev/null 2>&1
debug "Renumeration of $dev done."
}
#
# Use in manual loading. Parallelize loading
# firmwares to all of our devices
#
firmware_by_id() {
v_id=$1
p_id=$2
fw=$3
devices=`find_dev $v_id $p_id`
childs=""
for dev in $devices
do
(
set -e
fpga_firmware_device() {
id_str="$1"
devpath="$2"
load_fw_device "$dev" "$fw"
id_product=`echo "$id_str" | cut -d/ -f2`
bcd_device=`echo "$id_str" | cut -d/ -f3`
case "$id_str" in
e4e4/1131/101)
fw="FPGA_FXS.hex"
;;
e4e4/11[456]1/101)
fw="FPGA_${id_product}.hex"
;;
e4e4/1161/201)
fw="FPGA_${id_product}.${bcd_device}.hex"
;;
e4e4/*)
debug "No FPGA firmware for device $devpath ($id_str)"
return
;;
*)
return
;;
esac
debug "Loading $fw into $devpath"
load_fw_device "$devpath" "$fw"
sleep_if_race
) &
childs="$childs $!"
sleep 0.4
done
# Wait for specific childs to get their exit status
wait $childs
}
numdevs() {
v_ids="$1"
p_ids="$2"
id_str="$1"
for v in $v_ids
do
(
for p in $p_ids
do
find_dev $v $p
done
)
done | wc -w
#echo >&2 "numdevs($id_str)"
filter_devs "$id_str" | wc -l
}
wait_renumeration() {
num="$1"
v_ids="$2"
p_ids="$3"
num="$1"
id_str="$2"
caller="$3"
iter=10
while
n=`numdevs "$v_ids" "$p_ids"`
[ "$num" -gt "$n" ]
do
echo -n "."
sleep 1
done
echo "Got all $num devices"
prev=0
echo "Waiting renumeration ($caller)"
while
n=`numdevs "$id_str"`
[ "$num" -gt "$n" ]
do
if [ "$prev" -lt "$n" ]; then
echo -n "+"
else
echo -n "."
fi
sleep 1
prev="$n"
debug "wait($iter) (found $n from $num devices) ($caller)"
if ! iter=`expr $iter - 1`; then
echo "Timeout (found $n from $num devices) ($caller)"
break;
fi
done
echo "Got all $num devices ($caller)"
sleep 1 # Let everything settle
}
fpga_firmware_all_devices() {
echo "Loading FPGA firmwares"
devs=`filter_devs 'e4e4/11[3456]1/*'`
n=`echo "$devs" | wc -l`
echo "$devs" | (
while read id_str devpath; do
fpga_firmware_device "$id_str" "$devpath" &
done
sleep 1
echo "Wait for FPGA loading processes"
wait
)
wait_renumeration $numdevs 'e4e4/11[3456]2/*' "fpga_firmware_device"
}
reset_fpga() {
totaldevs=`numdevs e4e4 '11[3456][0123]'`
devices=`find_dev e4e4 '11[3456][12]'`
debug "Reseting devices [$totaldevs devices]"
for dev in $devices
do
debug "Resetting FPGA Firmware on $dev"
sleep_if_race
run_astribank_tool -D "$dev" -r full 2>&1 >/dev/null
done
if [ "$1" = 'wait' ]; then
wait_renumeration $totaldevs e4e4 '11[3456][03]'
fi
devices=`filter_devs 'e4e4/11[3456][124]/*'`
totaldevs=`numdevs 'e4e4/11[3456][124]/*'`
echo >&2 -- "Reseting devices [$totaldevs devices]"
echo "$devices" | grep -v '^$' | while read id_str dev
do
(
debug "Resetting FPGA Firmware on $dev"
sleep_if_race
run_astribank_tool -D "$dev" -r full >/dev/null 2>&1
) &
done
wait
if [ "$1" = 'wait' ]; then
wait_renumeration $totaldevs 'e4e4/11[3456][03]/*' "reset_fpga"
fi
}
usage() {
@@ -304,29 +455,28 @@ reset-wait)
reset)
reset_fpga
;;
list)
filter_devs 'e4e4/*/*'
exit 0
;;
xppdetect|load|usb)
numdevs=`numdevs e4e4 '11[3456][013]'`
$LOGGER -- "--------- FIRMWARE LOADING: ($1) [$numdevs devices]"
numdevs=`numdevs 'e4e4/11[3456][0134]/*'`
echo >&2 -- "--------- FIRMWARE LOADING: ($1) [$numdevs devices]"
load_usb_fw e4e4 1130 $USB_FW
load_usb_fw e4e4 1140 $USB_FW
load_usb_fw e4e4 1150 $USB_FW
load_usb_fw e4e4 1160 $USB_FW
load_usb_fw e4e4 1163 $USB_FW
wait_renumeration $numdevs e4e4 '11[3456]1'
usb_firmware_all_devices
if [ "$1" != 'usb' ]
then
firmware_by_id e4e4 1131 FPGA_FXS.hex
firmware_by_id e4e4 1141 FPGA_1141.hex
firmware_by_id e4e4 1151 FPGA_1151.hex
firmware_by_id e4e4 1161 FPGA_1161.hex
wait_renumeration $numdevs e4e4 '11[3456]2'
fpga_firmware_all_devices
fi
sleep 3 # Let it stabilize
$LOGGER -- "--------- FIRMWARE IS LOADED"
echo >&2 -- "--------- FIRMWARE IS LOADED"
exit 0
;;
recover-sb)
# Load a firmware that fixes a but which makes the Source Byte in the
# EEPROM reset and make the device appear like a Cypress dev kit:
load_usb_fw 04b4 8613 $USB_RECOV
;;
help)
usage
exit 0
@@ -374,32 +524,33 @@ udev_delayed_load() {
sleep 1
done
if [ $usb_dev_writable != 1 ]; then
$LOGGER "Device $DEVICE not writable. Can't load firmware."
echo >&2 "Device $DEVICE not writable. Can't load firmware."
return;
fi
$LOGGER "Trying to find what to do for product $PRODUCT, device $DEVICE"
prod_id=`echo "$PRODUCT" | cut -d/ -f2`
echo >&2 "Trying to find what to do for product $PRODUCT, device $DEVICE"
case "$PRODUCT" in
e4e4/11[3456]0/*|e4e4/1163/*)
FIRM_USB="$FIRMWARE_DIR/$USB_FW"
$LOGGER "Loading firmware '$FIRM_USB' into '$DEVICE'"
4b4/8613/*)
# This case is for a potentially-broken Astribank.
# In most systems you should not set udev rules for those to
# get here, as this is actually the ID of a Cypress dev-kit:
FIRM_USB="$FIRMWARE_DIR/$USB_RECOV"
echo >&2 "Loading recovery firmware '$FIRM_USB' into '$DEVICE'"
run_fxload -D "$DEVICE" -I "$FIRM_USB"
;;
e4e4/11[3456]0/*|e4e4/1163/*)
usb_firmware_device "$PRODUCT" "$DEVICE"
;;
e4e4/11[3456]1/*)
# There are potentially two separate udev events, for
# each of the two endpoints. Ignore the first interface:
case "$DEVPATH" in *.0) exit 0;; esac
if [ "$prod_id" = 1131 ]; then
FIRM_FPGA="FPGA_FXS.hex" # Legacy
else
FIRM_FPGA="FPGA_$prod_id.hex"
fi
sleep_if_race
load_fw_device "$DEVICE" "$FIRM_FPGA"
fpga_firmware_device "$PRODUCT" "$DEVICE" &
wait # parallel firmware loading
;;
esac
}
udev_delayed_load &
udev_delayed_load 2>&1 | $LOGGER &

View File

@@ -243,16 +243,17 @@ static int send_command(struct xtalk_device *xtalk_dev, struct xtalk_command *cm
{
int ret;
int len;
char *buf;
void *priv = xtalk_dev->transport_priv;
len = cmd->header.len;
cmd->header.seq = xtalk_dev->tx_sequenceno;
buf = (char *)cmd;
//printf("%s: len=%d\n", __FUNCTION__, len);
#if 0
extern FILE *fp;
char *buf;
buf = (char *)cmd;
if(fp) {
int i;

View File

@@ -30,11 +30,16 @@
#include <arpa/inet.h>
#include <debug.h>
#include <xusb.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
static const char rcsid[] = "$Id$";
#define DBG_MASK 0x01
#define TIMEOUT 500
#define MAX_RETRIES 10
struct xusb {
struct usb_device *dev;
@@ -56,6 +61,8 @@ struct xusb {
size_t packet_size;
};
static void xusb_init();
void xusb_init_spec(struct xusb_spec *spec, char *name,
uint16_t vendor_id, uint16_t product_id,
int nifaces, int iface, int nep, int ep_out, int ep_in)
@@ -363,9 +370,7 @@ struct xusb *xusb_find_iface(const char *devpath, int iface_num, int ep_out, int
struct usb_bus *bus;
DBG("\n");
usb_init();
usb_find_busses();
usb_find_devices();
xusb_init();
for (bus = usb_get_busses(); bus; bus = bus->next) {
int bus_num;
char tmppath[PATH_MAX + 1];
@@ -477,9 +482,7 @@ struct xlist_node *xusb_find_byproduct(const struct xusb_spec *specs, int numspe
ERR("Failed allocation new xlist");
goto fail_xlist;
}
usb_init();
usb_find_busses();
usb_find_devices();
xusb_init();
for (bus = usb_get_busses(); bus; bus = bus->next) {
for (dev = bus->devices; dev; dev = dev->next) {
struct usb_device_descriptor *dev_desc;
@@ -540,7 +543,10 @@ struct xusb *xusb_open_one(const struct xusb_spec *specs, int numspecs, xusb_fil
xusb = curr->data;
xlist_destroy(curr, NULL);
xlist_destroy(xusb_list, NULL);
xusb_claim_interface(xusb);
if(!xusb_claim_interface(xusb)) {
xusb_destroy(xusb);
return NULL;
}
xusb_showinfo(xusb);
break;
default:
@@ -657,12 +663,14 @@ int xusb_close(struct xusb *xusb)
int xusb_send(struct xusb *xusb, char *buf, int len, int timeout)
{
int ret;
int retries = 0;
dump_packet(LOG_DEBUG, DBG_MASK, __FUNCTION__, buf, len);
if(EP_OUT(xusb) & USB_ENDPOINT_IN) {
ERR("%s called with an input endpoint 0x%x\n", __FUNCTION__, EP_OUT(xusb));
return -EINVAL;
}
retry_write:
ret = usb_bulk_write(xusb->handle, EP_OUT(xusb), buf, len, timeout);
if(ret < 0) {
/*
@@ -672,17 +680,39 @@ int xusb_send(struct xusb *xusb, char *buf, int len, int timeout)
if(ret != -ENODEV) {
ERR("bulk_write to endpoint 0x%x failed: (%d) %s\n",
EP_OUT(xusb), ret, usb_strerror());
dump_packet(LOG_ERR, DBG_MASK, "xbus_send[ERR]", buf, len);
dump_packet(LOG_ERR, DBG_MASK, "xusb_send[ERR]", buf, len);
//exit(2);
} else {
DBG("bulk_write to endpoint 0x%x got ENODEV\n", EP_OUT(xusb));
xusb_close(xusb);
}
return ret;
} else if(ret != len) {
}
if(!ret) {
#if 0
FILE *fp;
fp = fopen("/tmp/xusb.log", "a");
if (!fp) {
ERR("%s: Failed writing to /tmp/xusb.log\n", __func__);
return -EFAULT;
}
fprintf(fp, "[%ld] bulk_write to endpoint 0x%x short write[%d]: (%d)\n",
time(NULL), EP_OUT(xusb), retries, ret);
fclose(fp);
#endif
ERR("bulk_write to endpoint 0x%x short write[%d]: (%d)\n",
EP_OUT(xusb), retries, ret);
if (retries++ > MAX_RETRIES) {
return -EFAULT;
}
usleep(100);
goto retry_write;
}
if(ret != len) {
ERR("bulk_write to endpoint 0x%x short write: (%d) %s\n",
EP_OUT(xusb), ret, usb_strerror());
dump_packet(LOG_ERR, DBG_MASK, "xbus_send[ERR]", buf, len);
dump_packet(LOG_ERR, DBG_MASK, "xusb_send[ERR]", buf, len);
return -EFAULT;
}
return ret;
@@ -691,11 +721,13 @@ int xusb_send(struct xusb *xusb, char *buf, int len, int timeout)
int xusb_recv(struct xusb *xusb, char *buf, size_t len, int timeout)
{
int ret;
int retries = 0;
if(EP_IN(xusb) & USB_ENDPOINT_OUT) {
ERR("%s called with an output endpoint 0x%x\n", __FUNCTION__, EP_IN(xusb));
return -EINVAL;
}
retry_read:
ret = usb_bulk_read(xusb->handle, EP_IN(xusb), buf, len, timeout);
if(ret < 0) {
DBG("bulk_read from endpoint 0x%x failed: (%d) %s\n",
@@ -703,6 +735,27 @@ int xusb_recv(struct xusb *xusb, char *buf, size_t len, int timeout)
memset(buf, 0, len);
return ret;
}
if(!ret) {
#if 0
FILE *fp;
fp = fopen("/tmp/xusb.log", "a");
if (!fp) {
ERR("%s: Failed writing to /tmp/xusb.log\n", __func__);
return -EFAULT;
}
fprintf(fp, "[%ld] bulk_read from endpoint 0x%x short read[%d]: (%d)\n",
time(NULL), EP_IN(xusb), retries, ret);
fclose(fp);
#endif
ERR("bulk_read to endpoint 0x%x short read[%d]: (%d)\n",
EP_IN(xusb), retries, ret);
if (retries++ > MAX_RETRIES) {
return -EFAULT;
}
usleep(100);
goto retry_read;
}
dump_packet(LOG_DEBUG, DBG_MASK, __FUNCTION__, buf, ret);
return ret;
}
@@ -724,3 +777,74 @@ int xusb_flushread(struct xusb *xusb)
}
return 0;
}
/*
* Serialize calls to usb_find_busses()/usb_find_devices()
*/
static const key_t SEM_KEY = 0x1a2b3c4d;
static int semid = -1; /* Failure */
static void xusb_lock_usb()
{
struct sembuf sembuf;
while (semid < 0) {
/* Maybe it was already created? */
semid = semget(SEM_KEY, 1, 0);
if (semid < 0) {
/* No, let's create ourselves */
semid = semget(SEM_KEY, 1, IPC_CREAT | IPC_EXCL | 0644);
if (semid < 0) {
/* Someone else won the race to create it */
if (errno != ENOENT)
ERR("%s: semget() failed: %s\n",
__func__, strerror(errno));
/* Retry */
continue;
}
/* Initialize */
if (semctl(semid, 0, SETVAL, 1) < 0)
ERR("%s: SETVAL() failed: %s\n",
__func__, strerror(errno));
}
}
DBG("%d: LOCKING\n", getpid());
sembuf.sem_num = 0;
sembuf.sem_op = -1;
sembuf.sem_flg = SEM_UNDO;
if (semop(semid, &sembuf, 1) < 0) {
ERR("%s: semop() failed: %s\n", __func__, strerror(errno));
}
DBG("%d: LOCKED\n", getpid());
}
static void xusb_unlock_usb()
{
struct sembuf sembuf;
DBG("%d: UNLOCKING\n", getpid());
sembuf.sem_num = 0;
sembuf.sem_op = 1;
sembuf.sem_flg = SEM_UNDO;
if (semop(semid, &sembuf, 1) < 0) {
ERR("%s: semop() failed: %s\n", __func__, strerror(errno));
}
DBG("%d: UNLOCKED\n", getpid());
}
static int initizalized = 0;
static void xusb_init()
{
if (!initizalized) {
if (!getenv("XUSB_NOLOCK"))
xusb_lock_usb();
usb_init();
usb_find_busses();
usb_find_devices();
initizalized = 1;
if (!getenv("XUSB_NOLOCK"))
xusb_unlock_usb();
}
}