我的建议是您发送字节的字符串表示形式而不是字节本身。
所以,试着改变
retval := UTL_TCP.write_line (bt_conn, l_sequence);
至
retval := UTL_TCP.write_raw (bt_conn, hextoraw(l_sequence));
我唯一的疑问是示例数据中的空格符号,但我认为他是偶然出现的。
在嗅探器的帮助下,您可以拦截来自 Oracle 的数据并将其与旧实用程序的数据进行比较。
更新(删除 - 不正确的协议实现)
更新 2
以下是 Polycomp 显示协议的实现,在文档中描述,可在 Internet 资源(链接1 、链接2 、链接 3)中找到。即使没有修改实现对您不起作用,它也包含许多有用的代码来学习如何处理raw
Oracle 中的值。
实用程序包头:
create or replace package POLYCOMP_UTIL is
-- PolyComp signboard interaction for Oracle
-- SERST (Serial status flag byte #5 constants) --------------------
-- B1 = 1 => "Interrupt Mode" = 0 => Normal DISPLAY Mode.
C_SERST_INTERRUPT constant binary_integer := 2; -- 00000010
-- B2 = 1 => More pages to come , = 0 => Last page.
C_SERST_MORE_PAGES constant binary_integer := 4; -- 00000100
-- B3 = 1 => "ACK" Requested , = 0 => No "ACK" required.
C_SERST_ACK constant binary_integer := 8; -- 00001000
-- B4 = 1 Schedule Mode Operation = 0 => No schedule operation.
C_SERST_SCHEDULE constant binary_integer := 16; --00010000
--------------------------------------------------------------------
-- Scheduling constants for pages ----------------------------------
-- days of the week
C_SCHEDULE_MONDAY constant binary_integer := 1; -- 00000001
C_SCHEDULE_TUESDAY constant binary_integer := 2; -- 00000010
C_SCHEDULE_WEDNESDAY constant binary_integer := 4; -- 00000100
C_SCHEDULE_THURSDAY constant binary_integer := 8; -- 00001000
C_SCHEDULE_FRIDAY constant binary_integer := 16; -- 00010000
C_SCHEDULE_SATURDAY constant binary_integer := 32; -- 00100000
C_SCHEDULE_SUNDAY constant binary_integer := 64; -- 01000000
C_SCHEDULE_ALL_WEEK_DAYS constant binary_integer := 128; -- 10000000
--------------------------------------------------------------------
-- freezing time (TEMP0) constants ---------------------------------
-- also defines scroll speed for bottom line (1- fastest, 9 - slowest)
C_TEMP0_CONST_BITS constant raw(1) := hextoraw('C0'); -- 11000000
C_TEMP0_AND_MASK constant raw(1) := hextoraw('3F'); -- 00111111
C_SCROLL_SPEED_1 constant binary_integer := 1; -- 0000 0001
C_SCROLL_SPEED_2 constant binary_integer := 2; -- 0000 0010
C_SCROLL_SPEED_3 constant binary_integer := 3; -- 0000 0011
C_SCROLL_SPEED_4 constant binary_integer := 4; -- 0000 0100
C_SCROLL_SPEED_5 constant binary_integer := 5; -- 0000 0101
C_SCROLL_SPEED_6 constant binary_integer := 6; -- 0000 0110
C_SCROLL_SPEED_7 constant binary_integer := 7; -- 0000 0111
C_SCROLL_SPEED_8 constant binary_integer := 8; -- 0000 1001
C_SCROLL_SPEED_9 constant binary_integer := 9; -- 0000 1001
C_DURATION_2_SEC constant binary_integer := C_SCROLL_SPEED_1;
C_DURATION_5_SEC constant binary_integer := C_SCROLL_SPEED_2;
C_DURATION_10_SEC constant binary_integer := C_SCROLL_SPEED_3;
C_DURATION_20_SEC constant binary_integer := C_SCROLL_SPEED_4;
C_DURATION_30_SEC constant binary_integer := C_SCROLL_SPEED_5;
C_DURATION_45_SEC constant binary_integer := C_SCROLL_SPEED_6;
C_DURATION_60_SEC constant binary_integer := C_SCROLL_SPEED_7;
C_DURATION_90_SEC constant binary_integer := C_SCROLL_SPEED_8;
C_DURATION_120_SEC constant binary_integer := C_SCROLL_SPEED_9;
-- Constants for page schedule override
C_PAGE_STATUS_TIMER constant binary_integer := 0; -- 00 00 0000
C_PAGE_STATUS_ON constant binary_integer := 16; -- 00 01 0000
C_PAGE_STATUS_OFF constant binary_integer := 32; -- 00 10 0000
--------------------------------------------------------------------
-- Function constants for pages ------------------------------------
C_DISPLAY_MODE_RANDOM constant binary_integer := 0; -- 0000 0000
C_DISPLAY_MODE_APPEAR constant binary_integer := 1; -- 0000 0001
C_DISPLAY_MODE_WIPE constant binary_integer := 2; -- 0000 0010
C_DISPLAY_MODE_OPEN constant binary_integer := 3; -- 0000 0011
C_DISPLAY_MODE_LOCK constant binary_integer := 4; -- 0000 0100
C_DISPLAY_MODE_ROTATE constant binary_integer := 5; -- 0000 0101
C_DISPLAY_MODE_RIGHT constant binary_integer := 6; -- 0000 0110
C_DISPLAY_MODE_LEFT constant binary_integer := 7; -- 0000 0111
C_DISPLAY_MODE_ROLL_UP constant binary_integer := 8; -- 0000 1000
C_DISPLAY_MODE_ROLL_DOWN constant binary_integer := 9; -- 0000 1001
C_DISPLAY_MODE_PING_PONG constant binary_integer := 10; -- 0000 1010
C_DISPLAY_MODE_FILL_UP constant binary_integer := 11; -- 0000 1011
C_DISPLAY_MODE_PAINT constant binary_integer := 12; -- 0000 1100
C_DISPLAY_MODE_FADE_IN constant binary_integer := 13; -- 0000 1101
C_DISPLAY_MODE_JUMP constant binary_integer := 14; -- 0000 1110
C_DISPLAY_MODE_SLIDE constant binary_integer := 15; -- 0000 1111
-- display clock on top line
C_DISPLAY_CLOCK constant binary_integer := 16; -- 00010000
-- display temperature on top line
C_DISPLAY_TEMPERATURE constant binary_integer := 32; -- 00100000
--------------------------------------------------------------------
-- Status constants for pages --------------------------------------
C_LINES_1_2_JOIN_BOLD constant binary_integer := 1; -- 0000 0001
C_LINES_3_4_JOIN_BOLD constant binary_integer := 2; -- 0000 0010
C_LINES_5_6_JOIN_BOLD constant binary_integer := 4; -- 0000 0100
C_LINES_7_8_JOIN_BOLD constant binary_integer := 8; -- 0000 1000
C_AUTOCENTER_TEXT constant binary_integer := 16; -- 0001 0000
C_FOREIGN_LANGUAGE constant binary_integer := 32; -- 0010 0000
C_BACKGROUND_COLOR_ON constant binary_integer := 64; -- 0010 0000
--------------------------------------------------------------------
-- Function returns escape sequence for switching to flash text.
function StartFlashText return varchar2;
-- Function returns escape sequence for switching to enlarged text.
function StartEnlargedText return varchar2;
-- Function returns escape sequence for switching text color to red.
function StartRedText return varchar2;
-- Function returns escape sequence for switching text color to green.
function StartGreenText return varchar2;
-- Function returns escape sequence for switching text color to yellow.
function StartYellowText return varchar2;
-- Function returns escape sequence for switching to multicolored text
function StartMulticolorText return varchar2;
-- Function returns escape sequence for resetting text output parameters
-- to defaults: not enlarged, not flashing, red color
function ResetToDefaultText return varchar2;
-- Function produces text for page header with given parameters
-- %param pSignNumber Signboard address, 1 to 127 - for concrete signboard, 0 - send to all connected boards
-- %param pLineCount Number of lines on page to fit signboard, 1 - 255 (?)
-- %param pSerstFlags Serial status flags (SERST), combination of:
-- C_SERST_INTERRUPT -- Single exceptionally displayed page which interrupts normal schedule,
-- only one page can be sent in this mode.
-- C_SERST_MORE_PAGES -- is current page NOT last
-- C_SERST_ACK -- seems to be never used over tcp/ip
-- C_SERST_SCHEDULE -- There are scheduling information present for this page
-- %param pPageNumber Sequential page number, 0 - 999. Page number 0 reserved for time setting command.
-- %return Text to concatenate with text of the page, use as pHeaderText parameter for MakePage function.
function MakePageHeaderText(
pSignNumber in binary_integer,
pLineCount in binary_integer,
pSerstFlags in binary_integer,
pPageNumber in binary_integer
) return varchar2;
-- Returns text for Page 000 which sets system time on the board
-- %param pDate date and time to set
function MakeTimeSetPageText(pDate in date) return varchar2;
-- Return text for bytes 9-25 of regular page to describe scheduling information
-- %param pStart start date and time to display page
-- %param pEnd end date and time of displaying page
-- %param pWeekDays schedule page display by days of the week, combination of C_SCHEDULE_xxx constants
-- %return Text to use with pScheduleText parameter of MakePage function
function MakeScheduleText(
pStart in date,
pEnd in date,
pWeekDays in binary_integer
) return varchar2;
-- Returns text for TEMP0 byte which follows a header or scheduling information if specified
-- %param pDurationOrSpeed One of C_SCROLL_SPEED_x or C_DURATION_xxx constants. Set of constants
-- to choose from depends on C_DISPLAY_MODE_xxx specified for pDisplayMode
-- parameter of MakeDisplayPageMode function (C_DISPLAY_MODE_SLIDE or others)
-- %param pStatusMode One of C_PAGE_STATUS_xxx constants controlling page usage.
-- %return Text which must be included into page packet after scheduling information if cpecified
-- or header string
function MakePageTemp0(
pDurationOrSpeed in binary_integer,
pStatusMode in binary_integer
) return varchar2;
-- Function makes string byte which
-- %param pDisplayMode One of C_DISPLAY_MODE_xxx constants.
-- %param pDisplayClock True for display time on top of the screen
-- %param pDisplayTemperature True for display temperature on top of the screen
-- %return char which encodes function parameters and must be present after TEMP0 byte
function MakePageDisplayMode(
pDisplayMode in binary_integer,
pDisplayClock in boolean,
pDisplayTemperature in boolean
) return varchar2;
-- Function encodes given display mode parameters to one char.
-- %param pJoinLines12 Join 2 first lines toghether for BOLD mode
-- %param pJoinLines34 Lines 3 and 4 joined for BOLD mode
-- %param pJoinLines56 Lines 5 and 6 joined for BOLD mode
-- %param pJoinLines78 Lines 7 and 8 joined for BOLD mode
-- %param pAutoCenter Text willbe centered on the screen
-- %param pUseForeignLanguage If true then page in foreign (not English) language
-- %param pUseBackgroundColor If true turns ON background colour
function MakePageStatus(
pJoinLines12 in boolean,
pJoinLines34 in boolean,
pJoinLines56 in boolean,
pJoinLines78 in boolean,
pAutoCenter in boolean,
pUseForeignLanguage in boolean,
pUseBackgroundColor in boolean
) return varchar2;
-- Makes full page packet from header and text to send to device
-- %param pHeaderText Page header from MakePageHeaderText function
-- %param pScheduleText Page schedule settings from MakeScheduleText function.
-- Applicable only if C_SERST_SCHEDULE bit set in header
-- %param pPageTemp0 Duration/speed and status information encoded by MakePageTemp0 function
-- %param pDisplayMode Display mode information encoded by MakePageDisplayMode function
-- %param pPageStatus Page status modes encoded by MakePageStatus function
-- %param pPageText Text to display on the page with incorporated control bytes to switch
-- character color and appearence (C_xxx_TEXT)
-- %return Raw sequence of bytes including end-of-text flag and check sum,
-- which can be sent to device using SendPages() procedure
function MakePage(
pHeaderText in varchar2,
pScheduleText in varchar2,
pPageTemp0 in varchar2,
pDisplayMode in varchar2,
pPageStatus in varchar2,
pPageText in varchar2
) return raw;
-- Make full page to set time and date on signboard
-- %param pSignNumber Signboard address, 1 to 127 - for concrete signboard, 0 - send to all connected boards
-- %param pDateTime Date and time to set on signboard.
-- %param pIsLastPage Must be true if there are no other pages in the packet
-- %return full raw page ready to be sent with SendPages() procedure.
function MakeTimeSetPage(
pSignNumber in binary_integer,
pDateTime in date,
pIsLastPage in boolean
) return raw;
-- Procedure sends sequence of prepared pages to signboard through tcp/ip connection to WizNet device.
-- %param pHost Host address of WizNet device, e.g. '10.2.30.4'
-- %param pPort Port number of WizNet device, usually 8000
-- %param pPageSet Raw sequence of bytes to send. Contains concatenated output of MakePage() function.
-- Page with C_SERST_INTERRUPT flag set is a special case and must be sent alone.
procedure SendPages(
pHost in varchar2,
pPort in binary_integer,
pPageSet in raw
);
end;
/
实用程序包正文:
create or replace package body POLYCOMP_UTIL is
-- PolyComp signboard interaction for Oracle
-- Header Sync (byte #1)
C_HEADER_SYNC constant char(1) := chr(0);
-- Etx, End-of-Header (byte #4)
C_HEADER_END constant char(1) := chr(3);
-- End-of-text mark
C_END_OF_TEXT constant char(1) := chr(4);
-- SERST (Serial status flag byte #5 constants) --------------------
-- Mask with fixed bits
-- B0 , B5 = 0
-- B6 – B7 All = 1.
-- B7 B6 B5 B4 B3 B2 B1
-- 1 1 0 0 0 0 0
C_SERST_CONST_BITS constant raw(1) := hextoraw('C0'); -- 11000000
C_SERST_AND_MASK constant raw(1) := hextoraw('1E'); -- 00011110
--------------------------------------------------------------------
-- Function constants for pages ------------------------------------
C_FUNCTION_CONST_BITS constant raw(1) := hextoraw('C0'); -- 11000000
C_FUNCTION_AND_MASK constant raw(1) := hextoraw('3F'); -- 00111111
--------------------------------------------------------------------
-- Status constants for pages --------------------------------------
C_STATUS_CONST_BITS constant raw(1) := hextoraw('80'); -- 10000000
C_STATUS_AND_MASK constant raw(1) := hextoraw('7F'); -- 01111111
--------------------------------------------------------------------
-- Constants for changing text apperance with C_CONTROL symbol -----
-- Escape symbol for control commands in message text
C_CONTROL constant char(1) := chr(28);
-- flash following text
C_FLASH_TEXT char(2) := C_CONTROL || 'F';
-- enlarge following text
C_ENLARGE_TEXT char(2) := C_CONTROL || 'E';
-- display following text in red
C_RED_TEXT char(2) := C_CONTROL || 'R';
-- display following text in green
C_GREEN_TEXT char(2) := C_CONTROL || 'G';
-- display following text in yellow
C_YELLOW_TEXT char(2) := C_CONTROL || 'Y';
-- display following text with multiple color (e.g. top - red, center - yellow, bottom - green)
C_MULTICOLOR_TEXT char(2) := C_CONTROL || 'M';
-- Restore default settings: not enlarged, not flashing, red.
C_DEFAULT_TEXT char(2) := C_CONTROL || 'D';
--------------------------------------------------------------------
-- Function gets as parameter integer value which fits into 1 byte (0 <= pValue <= 255)
-- and converts it into raw(1)
function byte_to_raw(pValue in binary_integer) return raw
is
begin
return utl_raw.substr( utl_raw.cast_from_binary_integer(pValue), 4, 1 );
end;
-- specification in package header
function StartFlashText return varchar2
is
begin
return C_FLASH_TEXT;
end;
-- specification in package header
function StartEnlargedText return varchar2
is
begin
return C_ENLARGE_TEXT;
end;
-- specification in package header
function StartRedText return varchar2
is
begin
return C_RED_TEXT;
end;
-- specification in package header
function StartGreenText return varchar2
is
begin
return C_GREEN_TEXT;
end;
-- specification in package header
function StartYellowText return varchar2
is
begin
return C_YELLOW_TEXT;
end;
-- specification in package header
function StartMulticolorText return varchar2
is
begin
return C_MULTICOLOR_TEXT;
end;
-- specification in package header
function ResetToDefaultText return varchar2
is
begin
return C_DEFAULT_TEXT;
end;
-- specification in package header
function MakePageHeaderText(
pSignNumber in binary_integer,
pLineCount in binary_integer,
pSerstFlags in binary_integer,
pPageNumber in binary_integer
) return varchar2
is
vSerstValue raw(1);
begin
vSerstValue := byte_to_raw(pSerstFlags);
vSerstValue := utl_raw.bit_and(vSerstValue, C_SERST_AND_MASK);
vSerstValue := utl_raw.bit_or(VserstValue, C_SERST_CONST_BITS);
return C_HEADER_SYNC || chr(pLineCount) || chr(pSignNumber) || C_HEADER_END ||
utl_raw.cast_to_varchar2(vSerstValue)|| ltrim(to_char(pPageNumber, '009'));
end;
-- specification in package header
function MakeTimeSetPageText(pDate in date) return varchar2
is
begin
return to_char(pDate, 'hh24missddmmd');
end;
-- specification in package header
function MakeScheduleText(
pStart in date,
pEnd in date,
pWeekDays in binary_integer
) return varchar2
is
begin
return to_char(pStart,'ddmm') || to_char(pEnd, 'ddmm') ||
to_char(pStart,'hhmm') || to_char(pEnd,'hhmm') ||
chr(pWeekDays);
end;
-- specification in package header
function MakePageTemp0(
pDurationOrSpeed in binary_integer,
pStatusMode in binary_integer
) return varchar2
is
vValue raw(1);
begin
vValue := byte_to_raw(pDurationOrSpeed + pStatusMode);
vValue := utl_raw.bit_and(vValue, C_TEMP0_AND_MASK);
vValue := utl_raw.bit_or(vValue, C_TEMP0_CONST_BITS);
return utl_raw.cast_to_varchar2(vValue);
end;
-- specification in package header
function MakePageDisplayMode(
pDisplayMode in binary_integer,
pDisplayClock in boolean,
pDisplayTemperature in boolean
) return varchar2
is
vMode binary_integer;
vValue raw(1);
begin
vMode := pDisplayMode;
if( pDisplayClock ) then
vMode := vMode + C_DISPLAY_CLOCK;
end if;
if( pDisplayTemperature ) then
vMode := vMode + C_DISPLAY_TEMPERATURE;
end if;
vValue := byte_to_raw(vMode);
vValue := utl_raw.bit_and(vValue, C_FUNCTION_AND_MASK);
vValue := utl_raw.bit_or(vValue, C_FUNCTION_CONST_BITS);
return utl_raw.cast_to_varchar2(vValue);
end;
-- specification in package header
function MakePageStatus(
pJoinLines12 in boolean,
pJoinLines34 in boolean,
pJoinLines56 in boolean,
pJoinLines78 in boolean,
pAutoCenter in boolean,
pUseForeignLanguage in boolean,
pUseBackgroundColor in boolean
) return varchar2
is
vStatus binary_integer;
vValue raw(1);
begin
vStatus := 0;
if(pJoinLines12) then
vStatus := vStatus + C_LINES_1_2_JOIN_BOLD;
end if;
if(pJoinLines34) then
vStatus := vStatus + C_LINES_3_4_JOIN_BOLD;
end if;
if(pJoinLines56) then
vStatus := vStatus + C_LINES_5_6_JOIN_BOLD;
end if;
if(pJoinLines78) then
vStatus := vStatus + C_LINES_7_8_JOIN_BOLD;
end if;
if(pAutoCenter) then
vStatus := vStatus + C_AUTOCENTER_TEXT;
end if;
if(pUseForeignLanguage) then
vStatus := vStatus + C_FOREIGN_LANGUAGE;
end if;
if(pUseBackgroundColor) then
vStatus := vStatus + C_BACKGROUND_COLOR_ON;
end if;
vValue := byte_to_raw(vStatus);
vValue := utl_raw.bit_and(vValue, C_STATUS_AND_MASK);
vValue := utl_raw.bit_or(vValue, C_STATUS_CONST_BITS);
return utl_raw.cast_to_varchar2(vValue);
end;
-- specification in package header
function MakePage(
pHeaderText in varchar2,
pScheduleText in varchar2,
pPageTemp0 in varchar2,
pDisplayMode in varchar2,
pPageStatus in varchar2,
pPageText in varchar2
) return raw
is
vPage raw(32565);
vCheckSum raw(1) := hextoraw('00');
begin
vPage := utl_raw.cast_to_raw(
pHeaderText ||
pScheduleText || pPageTemp0 || pDisplayMode || pPageStatus ||
pPageText || C_END_OF_TEXT
);
for i in 1 .. utl_raw.length(vPage) loop
vCheckSum := utl_raw.bit_xor(vCheckSum, utl_raw.substr(vPage,i,1));
end loop;
return utl_raw.concat(vPage, vCheckSum);
end;
-- specification in package header
function MakeTimeSetPage(
pSignNumber in binary_integer,
pDateTime in date,
pIsLastPage in boolean
) return raw
is
vSerstValue binary_integer := C_SERST_SCHEDULE;
begin
if(not pIsLastPage) then
vSerstValue := vSerstValue + C_SERST_MORE_PAGES;
end if;
return MakePage(
pHeaderText => MakePageHeaderText(
pSignNumber => pSignNumber,
pLineCount => 0,
pSerstFlags => vSerstValue,
pPageNumber => 0 -- control page
),
pScheduleText => MakeTimeSetPageText(pDateTime),
pPageTemp0 => null,
pDisplayMode => null,
pPageStatus => null,
pPageText => null
);
end;
-- specification in package header
procedure SendPages(
pHost in varchar2,
pPort in binary_integer,
pPageSet in raw
)
is
C_CHUNK_SIZE constant binary_integer := 16*1024*8; -- 16 KB
vConn UTL_TCP.Connection;
vPagesLength binary_integer;
vRC binary_integer;
vTimeout binary_integer;
vBytesSent binary_integer;
vCurChunkSize binary_integer;
begin
vPagesLength := utl_raw.length(pPageSet);
-- Set timeout based on baud rate 9600 plus 256Kb tcp/ip network overhead and minimum at 10 seconds.
-- Calculating timeout such a way assumes that no significant buffering performed at receiver which
-- becomes true in case of WizNet device buffer overflow.
-- Seems that oracle ignores timeout for write operation in current versions but anyway
-- this must be taken into account.
vTimeout := greatest(10, ceil( (C_CHUNK_SIZE*8*1.04)/(256*1024) ) + ceil( (C_CHUNK_SIZE*8)/9600 ) );
vConn := UTL_TCP.open_connection (
remote_host => pHost,
remote_port => pPort,
in_buffer_size => 0,
out_buffer_size => 16*1024*8, -- 16KB
tx_timeout => vTimeout
);
begin
vBytesSent := 0;
while (vBytesSent < vPagesLength) loop
vCurChunkSize := least(C_CHUNK_SIZE, vPagesLength - vBytesSent);
vRC := UTL_TCP.write_raw(
vConn,
utl_raw.substr(pPageSet, vBytesSent+1, vCurChunkSize),
vCurChunkSize
);
if(vRC < vCurChunkSize) then
raise_application_error(-20001,
'Error sending chunk: only ' || vRC || ' bytes out of ' || vCurChunkSize || ' sent.'
);
end if;
vBytesSent := vBytesSent + vCurChunkSize;
end loop;
UTL_TCP.Flush(vConn);
UTL_TCP.close_connection(vConn);
exception
when others then begin
UTL_TCP.close_connection(vConn);
raise;
end;
end;
end;
end;
/
以中断模式显示单页的示例:
declare
vHeader varchar2(10);
vSchedule varchar2(100);
vTemp0 varchar2(1);
vDisplayMode varchar2(1);
vStatus varchar2(1);
vText varchar2(32767);
vPage raw(32767);
begin
vHeader := polycomp_util.MakePageHeaderText(1,1, polycomp_util.C_SERST_INTERRUPT, 1);
vTemp0 := polycomp_util.MakePageTemp0(polycomp_util.C_SCROLL_SPEED_4, polycomp_util.C_PAGE_STATUS_ON);
vDisplayMode := polycomp_util.MakePageDisplayMode(polycomp_util.C_DISPLAY_MODE_SLIDE, false, false);
vStatus := polycomp_util.MakePageStatus(false, false, false, false, false, false, false);
vText := polycomp_util.StartGreenText || '<-- SLIDING green TEXT -->';
vPage := polycomp_util.MakePage(vHeader, null, vTemp0, vDisplayMode, vStatus, vText);
polycomp_util.SendPages(vPage);
end;