diff --git a/bacnet-stack/dlmstp.c b/bacnet-stack/dlmstp.c deleted file mode 100644 index 55429d57..00000000 --- a/bacnet-stack/dlmstp.c +++ /dev/null @@ -1,92 +0,0 @@ -/*####COPYRIGHTBEGIN#### - ------------------------------------------- - Copyright (C) 2005 Steve Karg - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to: - The Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307 - USA. - - As a special exception, if other files instantiate templates or - use macros or inline functions from this file, or you compile - this file and link it with other works to produce a work based - on this file, this file does not by itself cause the resulting - work to be covered by the GNU General Public License. However - the source code for this file must still be made available in - accordance with section (3) of the GNU General Public License. - - This exception does not invalidate any other reasons why a work - based on this file might be covered by the GNU General Public - License. - ------------------------------------------- -####COPYRIGHTEND####*/ -#include -#include -#include -#include "bacdef.h" -#include "mstp.h" -#include "dlmstp.h" - -void dlmstp_init(void) -{ - -} - -void dlmstp_cleanup(void) -{ - -} - -/* returns number of bytes sent on success, negative on failure */ -int dlmstp_send_pdu(BACNET_ADDRESS * dest, /* destination address */ - uint8_t * pdu, /* any data to be sent - may be null */ - unsigned pdu_len) -{ /* number of bytes of data */ - - (void) dest; - (void) pdu; - (void) pdu_len; - - return 0; -} - -/* returns the number of octets in the PDU, or zero on failure */ -uint16_t dlmstp_receive(BACNET_ADDRESS * src, /* source address */ - uint8_t * pdu, /* PDU data */ - uint16_t max_pdu, /* amount of space available in the PDU */ - unsigned timeout) -{ /* milliseconds to wait for a packet */ - (void) src; - (void) pdu; - (void) max_pdu; - (void) timeout; - - return 0; -} - -void dlmstp_set_my_address(BACNET_ADDRESS * my_address) -{ - return; -} - -void dlmstp_get_my_address(BACNET_ADDRESS * my_address) -{ - return; -} - -void dlmstp_get_broadcast_address(BACNET_ADDRESS * dest) -{ /* destination address */ - return; -} diff --git a/bacnet-stack/dlmstp.h b/bacnet-stack/dlmstp.h index 850c5d28..a3eddd4e 100644 --- a/bacnet-stack/dlmstp.h +++ b/bacnet-stack/dlmstp.h @@ -44,12 +44,21 @@ #define MAX_HEADER (2+1+1+1+2+1+2+1) #define MAX_MPDU (MAX_HEADER+MAX_PDU) +typedef struct dlmstp_packet +{ + BACNET_ADDRESS address; + unsigned pdu_len; + uint8_t pdu[MAX_MPDU]; +} DLMSTP_PACKET; + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ void dlmstp_init(void); void dlmstp_cleanup(void); + void dlmstp_task(void); + void dlmstp_millisecond_timer(void); /* returns number of bytes sent on success, negative on failure */ int dlmstp_send_pdu(BACNET_ADDRESS * dest, /* destination address */ @@ -61,8 +70,15 @@ extern "C" { uint8_t * pdu, /* PDU data */ uint16_t max_pdu, /* amount of space available in the PDU */ unsigned timeout); /* milliseconds to wait for a packet */ + +/* function for MS/TP state machine to use to get a packet + to transmit. It returns the number of bytes in the + packet, or 0 if none. */ + int dlmstp_get_transmit_pdu(BACNET_ADDRESS * dest, /* destination address */ + uint8_t * pdu); /* any data to be sent - may be null */ + - void dlmstp_set_my_address(BACNET_ADDRESS * my_address); + void dlmstp_set_my_address(uint8_t my_address); void dlmstp_get_my_address(BACNET_ADDRESS * my_address); void dlmstp_get_broadcast_address(BACNET_ADDRESS * dest); /* destination address */ diff --git a/bacnet-stack/ports/pic18/BACnet-Server.mcp b/bacnet-stack/ports/pic18/BACnet-Server.mcp new file mode 100644 index 00000000..cf4a4372 --- /dev/null +++ b/bacnet-stack/ports/pic18/BACnet-Server.mcp @@ -0,0 +1,131 @@ +[HEADER] +magic_cookie={66E99B07-E706-4689-9E80-9B2582898A13} +file_version=1.0 +[PATH_INFO] +dir_src= +dir_bin= +dir_tmp= +dir_sin= +dir_inc=C:\code\bacnet-stack;C:\code\bacnet-stack\demo\handler;C:\code\bacnet-stack\demo\object;C:\code\bacnet-stack\ports\pic18 +dir_lib=C:\mcc18\lib +dir_lkr= +[CAT_FILTERS] +filter_src=*.asm;*.c +filter_inc=*.h;*.inc +filter_obj=*.o +filter_lib=*.lib +filter_lkr=*.lkr +[OTHER_FILES] +file_000=no +file_001=no +file_002=no +file_003=no +file_004=no +file_005=no +file_006=no +file_007=no +file_008=no +file_009=no +file_010=no +file_011=no +file_012=no +file_013=no +file_014=no +file_015=no +file_016=no +file_017=no +file_018=no +file_019=no +file_020=no +file_021=no +file_022=no +file_023=no +file_024=no +file_025=no +file_026=no +file_027=no +file_028=no +file_029=no +file_030=no +file_031=no +file_032=no +file_033=no +file_034=no +file_035=no +file_036=no +file_037=no +file_038=no +file_039=no +file_040=no +file_041=no +file_042=no +file_043=no +file_044=no +file_045=no +file_046=no +file_047=no +file_048=no +file_049=no +file_050=no +file_051=no +[FILE_INFO] +file_000=C:\code\bacnet-stack\abort.c +file_001=C:\code\bacnet-stack\apdu.c +file_002=C:\code\bacnet-stack\bacapp.c +file_003=C:\code\bacnet-stack\bacdcode.c +file_004=C:\code\bacnet-stack\bacerror.c +file_005=C:\code\bacnet-stack\bacstr.c +file_006=C:\code\bacnet-stack\crc.c +file_007=C:\code\bacnet-stack\datalink.c +file_008=C:\code\bacnet-stack\dcc.c +file_009=C:\code\bacnet-stack\iam.c +file_010=C:\code\bacnet-stack\mstp.c +file_011=C:\code\bacnet-stack\npdu.c +file_012=C:\code\bacnet-stack\rd.c +file_013=C:\code\bacnet-stack\reject.c +file_014=C:\code\bacnet-stack\ringbuf.c +file_015=C:\code\bacnet-stack\rp.c +file_016=C:\code\bacnet-stack\whois.c +file_017=C:\code\bacnet-stack\demo\handler\h_dcc.c +file_018=C:\code\bacnet-stack\demo\handler\h_rd.c +file_019=main.c +file_020=C:\code\bacnet-stack\demo\object\tiny_dev.c +file_021=dlmstp.c +file_022=C:\code\bacnet-stack\wp.h +file_023=C:\code\bacnet-stack\abort.h +file_024=C:\code\bacnet-stack\apdu.h +file_025=C:\code\bacnet-stack\bacapp.h +file_026=C:\code\bacnet-stack\bacdcode.h +file_027=C:\code\bacnet-stack\bacdef.h +file_028=C:\code\bacnet-stack\bacenum.h +file_029=C:\code\bacnet-stack\bacerror.h +file_030=C:\code\bacnet-stack\bacstr.h +file_031=C:\code\bacnet-stack\config.h +file_032=C:\code\bacnet-stack\crc.h +file_033=C:\code\bacnet-stack\datalink.h +file_034=C:\code\bacnet-stack\dcc.h +file_035=C:\code\bacnet-stack\dlmstp.h +file_036=C:\code\bacnet-stack\iam.h +file_037=C:\code\bacnet-stack\mstp.h +file_038=C:\code\bacnet-stack\npdu.h +file_039=C:\code\bacnet-stack\rd.h +file_040=C:\code\bacnet-stack\reject.h +file_041=C:\code\bacnet-stack\ringbuf.h +file_042=C:\code\bacnet-stack\rp.h +file_043=C:\code\bacnet-stack\rs485.h +file_044=C:\code\bacnet-stack\whois.h +file_045=C:\code\bacnet-stack\demo\handler\client.h +file_046=C:\code\bacnet-stack\demo\handler\handlers.h +file_047=C:\code\bacnet-stack\demo\object\ai.h +file_048=C:\code\bacnet-stack\demo\object\ao.h +file_049=C:\code\bacnet-stack\demo\object\device.h +file_050=stdbool.h +file_051=stdint.h +[SUITE_INFO] +suite_guid={5B7D72DD-9861-47BD-9F60-2BE967BF8416} +suite_state= +[TOOL_SETTINGS] +TS{DD2213A8-6310-47B1-8376-9430CDFC013F}= +TS{BFD27FBA-4A02-4C0E-A5E5-B812F3E7707C}=/o"$(TARGETBASE).cof" /M"$(BINDIR_)$(TARGETBASE).map" +TS{C2AF05E7-1416-4625-923D-E114DB6E2B96}=-DPRINT_ENABLED=0 -DBACDL_MSTP -DBIG_ENDIAN=1 -mL -Ls -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa- +TS{ADE93A55-C7C7-4D4D-A4BA-59305F7D0391}= diff --git a/bacnet-stack/ports/pic18/BACnet-Server.mcw b/bacnet-stack/ports/pic18/BACnet-Server.mcw new file mode 100644 index 00000000..c7ac1e2f Binary files /dev/null and b/bacnet-stack/ports/pic18/BACnet-Server.mcw differ diff --git a/bacnet-stack/ports/pic18/bacnet.mcp b/bacnet-stack/ports/pic18/bacnet.mcp index 5f98f1d8..df2429fe 100644 --- a/bacnet-stack/ports/pic18/bacnet.mcp +++ b/bacnet-stack/ports/pic18/bacnet.mcp @@ -6,7 +6,7 @@ dir_src= dir_bin= dir_tmp= dir_sin= -dir_inc=c:\mcc18\h;c:\code\bacnet-stack;c:\code\bacnet-stack\ports\pic18 +dir_inc=c:\mcc18\h;c:\code\bacnet-stack;c:\code\bacnet-stack\ports\pic18;c:\code\bacnet-stack\demo\object;c:\code\bacnet-stack\demo\handler dir_lib=c:\mcc18\lib dir_lkr= [CAT_FILTERS] @@ -70,6 +70,9 @@ file_050=no file_051=no file_052=no file_053=no +file_054=no +file_055=no +file_056=no [FILE_INFO] file_000=rs485.c file_001=main.c @@ -85,53 +88,56 @@ file_010=C:\code\bacnet-stack\bacerror.c file_011=C:\code\bacnet-stack\bigend.c file_012=C:\code\bacnet-stack\crc.c file_013=C:\code\bacnet-stack\datalink.c -file_014=C:\code\bacnet-stack\device.c -file_015=C:\code\bacnet-stack\dlmstp.c -file_016=C:\code\bacnet-stack\iam.c -file_017=C:\code\bacnet-stack\mstp.c -file_018=C:\code\bacnet-stack\npdu.c -file_019=C:\code\bacnet-stack\reject.c -file_020=C:\code\bacnet-stack\ringbuf.c -file_021=C:\code\bacnet-stack\address.c -file_022=C:\code\bacnet-stack\tsm.c -file_023=C:\code\bacnet-stack\ao.c -file_024=C:\code\bacnet-stack\ai.c -file_025=C:\code\bacnet-stack\handlers.c -file_026=C:\code\bacnet-stack\wp.c +file_014=C:\code\bacnet-stack\dlmstp.c +file_015=C:\code\bacnet-stack\iam.c +file_016=C:\code\bacnet-stack\mstp.c +file_017=C:\code\bacnet-stack\npdu.c +file_018=C:\code\bacnet-stack\reject.c +file_019=C:\code\bacnet-stack\ringbuf.c +file_020=C:\code\bacnet-stack\wp.c +file_021=C:\code\bacnet-stack\demo\object\ai.c +file_022=C:\code\bacnet-stack\demo\object\ao.c +file_023=C:\code\bacnet-stack\dcc.c +file_024=C:\code\bacnet-stack\bacstr.c +file_025=C:\code\bacnet-stack\bacapp.c +file_026=C:\code\bacnet-stack\demo\object\tiny_dev.c file_027=stdbool.h file_028=stdint.h file_029=init.h file_030=timer.h -file_031=C:\code\bacnet-stack\tsm.h -file_032=C:\code\bacnet-stack\whois.h -file_033=C:\code\bacnet-stack\abort.h -file_034=C:\code\bacnet-stack\address.h -file_035=C:\code\bacnet-stack\apdu.h -file_036=C:\code\bacnet-stack\bacdcode.h -file_037=C:\code\bacnet-stack\bacdef.h -file_038=C:\code\bacnet-stack\bacenum.h -file_039=C:\code\bacnet-stack\bacerror.h -file_040=C:\code\bacnet-stack\bigend.h -file_041=C:\code\bacnet-stack\bits.h -file_042=C:\code\bacnet-stack\bytes.h -file_043=C:\code\bacnet-stack\config.h -file_044=C:\code\bacnet-stack\crc.h -file_045=C:\code\bacnet-stack\datalink.h -file_046=C:\code\bacnet-stack\device.h -file_047=C:\code\bacnet-stack\dlmstp.h -file_048=C:\code\bacnet-stack\mstp.h -file_049=C:\code\bacnet-stack\npdu.h -file_050=C:\code\bacnet-stack\reject.h -file_051=C:\code\bacnet-stack\ringbuf.h -file_052=C:\code\bacnet-stack\rs485.h -file_053=18f252.lkr +file_031=C:\code\bacnet-stack\whois.h +file_032=C:\code\bacnet-stack\abort.h +file_033=C:\code\bacnet-stack\apdu.h +file_034=C:\code\bacnet-stack\bacdcode.h +file_035=C:\code\bacnet-stack\bacdef.h +file_036=C:\code\bacnet-stack\bacenum.h +file_037=C:\code\bacnet-stack\bacerror.h +file_038=C:\code\bacnet-stack\bigend.h +file_039=C:\code\bacnet-stack\bits.h +file_040=C:\code\bacnet-stack\bytes.h +file_041=C:\code\bacnet-stack\config.h +file_042=C:\code\bacnet-stack\crc.h +file_043=C:\code\bacnet-stack\datalink.h +file_044=C:\code\bacnet-stack\dlmstp.h +file_045=C:\code\bacnet-stack\mstp.h +file_046=C:\code\bacnet-stack\npdu.h +file_047=C:\code\bacnet-stack\reject.h +file_048=C:\code\bacnet-stack\ringbuf.h +file_049=C:\code\bacnet-stack\rs485.h +file_050=C:\code\bacnet-stack\demo\object\ai.h +file_051=C:\code\bacnet-stack\demo\object\ao.h +file_052=C:\code\bacnet-stack\demo\object\device.h +file_053=C:\code\bacnet-stack\dcc.h +file_054=C:\code\bacnet-stack\bacstr.h +file_055=C:\code\bacnet-stack\bacapp.h +file_056=18f252.lkr [SUITE_INFO] suite_guid={5B7D72DD-9861-47BD-9F60-2BE967BF8416} suite_state= [TOOL_SETTINGS] TS{DD2213A8-6310-47B1-8376-9430CDFC013F}= TS{BFD27FBA-4A02-4C0E-A5E5-B812F3E7707C}=/m"$(BINDIR_)$(TARGETBASE).map" /o"$(TARGETBASE).cof" -TS{C2AF05E7-1416-4625-923D-E114DB6E2B96}=-DBACDL_MSTP +TS{C2AF05E7-1416-4625-923D-E114DB6E2B96}=-DBACDL_MSTP -DTSM_ENABLED=0 -DPRINT_ENABLED=0 -mL TS{ADE93A55-C7C7-4D4D-A4BA-59305F7D0391}= TS{DD2213A8-6310-47B1-8376-9430CDFC013F}001= TS{BFD27FBA-4A02-4C0E-A5E5-B812F3E7707C}001=/o"$(TARGETBASE).cof" @@ -139,6 +145,3 @@ TS{C2AF05E7-1416-4625-923D-E114DB6E2B96}001=-Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa- TS{ADE93A55-C7C7-4D4D-A4BA-59305F7D0391}001= [ACTIVE_FILE_SETTINGS] TS{C2AF05E7-1416-4625-923D-E114DB6E2B96}001_active=yes -[TOOL_LOC_STAMPS] -tool_loc{96C98149-AA1B-4CF9-B967-FAE79CAB663C}=C:\mcc18\bin\mplink.exe -tool_loc{E56A1C86-9D32-4DF6-8C34-FE0388B1B644}=C:\mcc18\bin\mcc18.exe diff --git a/bacnet-stack/ports/pic18/bacnet.mcw b/bacnet-stack/ports/pic18/bacnet.mcw index f64e23ba..fd405142 100644 Binary files a/bacnet-stack/ports/pic18/bacnet.mcw and b/bacnet-stack/ports/pic18/bacnet.mcw differ diff --git a/bacnet-stack/ports/pic18/dlmstp.c b/bacnet-stack/ports/pic18/dlmstp.c new file mode 100644 index 00000000..26bdf0d1 --- /dev/null +++ b/bacnet-stack/ports/pic18/dlmstp.c @@ -0,0 +1,194 @@ +/************************************************************************** +* +* Copyright (C) 2006 Steve Karg +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*********************************************************************/ +#include +#include +#include +#include +#include "bacdef.h" +#include "mstp.h" +#include "dlmstp.h" +#include "ringbuf.h" +#include "rs485.h" + +#define RB_PACKET_COUNT 2 +#define RB_PACKET_SIZE sizeof(DLMSTP_PACKET) +static RING_BUFFER Receive_Buffer; +static char Receive_Data_Store[RB_PACKET_COUNT * RB_PACKET_SIZE]; +static RING_BUFFER Transmit_Buffer; +static char Transmit_Data_Store[RB_PACKET_COUNT * RB_PACKET_SIZE]; + +volatile struct mstp_port_struct_t MSTP_Port; /* port data */ +static uint8_t MSTP_MAC_Address = 0x05; /* local MAC address */ +DLMSTP_PACKET Temp_Packet; + +void dlmstp_init(void) +{ + Ringbuf_Init(&Receive_Buffer, + &Receive_Data_Store[0], + RB_PACKET_SIZE, + RB_PACKET_COUNT); + Ringbuf_Init(&Transmit_Buffer, + &Transmit_Data_Store[0], + RB_PACKET_SIZE, + RB_PACKET_COUNT); + RS485_Initialize(); + MSTP_Init(&MSTP_Port, MSTP_MAC_Address); +} + +void dlmstp_cleanup(void) +{ + /* nothing to do for static buffers */ +} + +/* returns number of bytes sent on success, negative on failure */ +int dlmstp_send_pdu(BACNET_ADDRESS * dest, /* destination address */ + uint8_t * pdu, /* any data to be sent - may be null */ + unsigned pdu_len) +{ /* number of bytes of data */ + bool status; + int bytes_sent = 0; + + memmove(&Temp_Packet.address,dest,sizeof(Temp_Packet.address)); + Temp_Packet.pdu_len = pdu_len; + memmove(Temp_Packet.pdu,pdu,sizeof(Temp_Packet.pdu)); + status = Ringbuf_Put(&Transmit_Buffer, &Temp_Packet); + if (status) + bytes_sent = pdu_len; + + return bytes_sent; +} + +/* function for MS/TP to use to get a packet to transmit + returns the number of bytes in the packet, or 0 if none. */ +int dlmstp_get_transmit_pdu(BACNET_ADDRESS * dest, /* destination address */ + uint8_t * pdu) /* any data to be sent - may be null */ +{ + bool status; + DLMSTP_PACKET *packet; + unsigned pdu_len = 0; + + if (!Ringbuf_Empty(&Transmit_Buffer)) + { + packet = Ringbuf_Pop_Front(&Transmit_Buffer); + memmove(dest,&packet->address,sizeof(packet->address)); + pdu_len = packet->pdu_len; + memmove(pdu,packet->pdu,sizeof(packet.pdu)); + } + + return pdu_len; +} + +void dlmstp_task(void) +{ + RS485_Check_UART_Data(&MSTP_Port); + MSTP_Receive_Frame_FSM(&MSTP_Port); + + RS485_Process_Tx_Message(); + MSTP_Master_Node_FSM(&MSTP_Port); +} + +/* called about once a millisecond */ +void dlmstp_millisecond_timer(void) +{ + MSTP_Millisecond_Timer(&MSTP_Port); +} + +/* returns the number of octets in the PDU, or zero on failure */ +/* This function is expecting to be polled. */ +uint16_t dlmstp_receive(BACNET_ADDRESS * src, /* source address */ + uint8_t * pdu, /* PDU data */ + uint16_t max_pdu, /* amount of space available in the PDU */ + unsigned timeout) +{ + DLMSTP_PACKET *packet; + + (void) timeout; + /* see if there is a packet available */ + if (!Ringbuf_Empty(&Receive_Buffer)) + { + packet = (char *)Ringbuf_Pop_Front(&Receive_Buffer); + memmove(src,&packet->address,sizeof(packet->address)); + pdu_len = packet->pdu_len; + memmove(pdu,packet->pdu,max_pdu); + } + + return pdu_len; +} + +/* for the MS/TP state machine to use for putting received data */ +uint16_t dlmstp_put_receive(BACNET_ADDRESS * src, /* source address */ + uint8_t * pdu, /* PDU data */ + uint16_t pdu_len) +{ + bool status; + int bytes_put = 0; + + memmove(&Temp_Packet.address,src,sizeof(Temp_Packet.address)); + Temp_Packet.pdu_len = pdu_len; + memmove(Temp_Packet.pdu,pdu,sizeof(Temp_Packet.pdu)); + status = Ringbuf_Put(&Receive_Buffer, &Temp_Packet); + if (status) + bytes_put = pdu_len; + + return bytes_put; +} + +void dlmstp_set_my_address(uint8_t mac_address) +{ + /* FIXME: Master Nodes can only have address 1-127 */ + MSTP_MAC_Address = mac_address; + + return; +} + +void dlmstp_get_my_address(BACNET_ADDRESS * my_address) +{ + my_address->mac_len = 1; + my_address->mac[0] = MSTP_MAC_Address; + my_address->net = 0; /* local only, no routing */ + my_address->len = 0; + for (i = 0; i < MAX_MAC_LEN; i++) { + my_address->adr[i] = 0; + } + + return; +} + +void dlmstp_get_broadcast_address(BACNET_ADDRESS * dest) +{ /* destination address */ + int i = 0; /* counter */ + + if (dest) { + dest->mac_len = 1; + dest->mac[0] = MSTP_BROADCAST_ADDRESS; + dest->net = BACNET_BROADCAST_NETWORK; + dest->len = 0; /* len=0 denotes broadcast address */ + for (i = 0; i < MAX_MAC_LEN; i++) { + dest->adr[i] = 0; + } + } + + return; +} diff --git a/bacnet-stack/ports/pic18/main.c b/bacnet-stack/ports/pic18/main.c index cf2ef1ae..14ed3362 100644 --- a/bacnet-stack/ports/pic18/main.c +++ b/bacnet-stack/ports/pic18/main.c @@ -32,10 +32,102 @@ #include "ringbuf.h" #include "init.h" #include "timer.h" +#include "datalink.h" +#include "handlers.h" +#include "device.h" #include "hardware.h" +#include "iam.h" +/* for readproperty handler */ +#include "config.h" +#include "txbuf.h" +#include "bacdef.h" +#include "bacdcode.h" +#include "bacerror.h" +#include "apdu.h" +#include "npdu.h" +#include "abort.h" +#include "rp.h" + +/* buffer used for encoding RP apdu */ +static uint8_t Temp_Buf[MAX_APDU]; +/* buffer used for receiving */ +static uint8_t Rx_Buf[MAX_MPDU] = { 0 }; +/* address where message came from */ +static BACNET_ADDRESS src; +/* address used to send */ +static BACNET_ADDRESS my_address; + +/* see demo/handler/h_rp.c for a more complete example */ +void My_Read_Property_Handler(uint8_t * service_request, + uint16_t service_len, + BACNET_ADDRESS * src, BACNET_CONFIRMED_SERVICE_DATA * service_data) +{ + BACNET_READ_PROPERTY_DATA data; + int len = 0; + int pdu_len = 0; + bool send = false; + bool error = false; + int bytes_sent = 0; + BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT; + BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT; + + len = rp_decode_service_request(service_request, service_len, &data); + /* prepare a reply */ + datalink_get_my_address(&my_address); + /* encode the NPDU portion of the packet */ + pdu_len = npdu_encode_apdu(&Handler_Transmit_Buffer[0], src, &my_address, false, /* true for confirmed messages */ + MESSAGE_PRIORITY_NORMAL); + /* bad decoding - send an abort */ + if (len == -1) { + pdu_len += abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, ABORT_REASON_OTHER); + send = true; + } else if (service_data->segmented_message) { + pdu_len += abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, + ABORT_REASON_SEGMENTATION_NOT_SUPPORTED); + send = true; + } else { + switch (data.object_type) { + case OBJECT_DEVICE: + /* FIXME: probably need a length limitation sent with encode */ + if (data.object_instance == Device_Object_Instance_Number()) { + len = Device_Encode_Property_APDU(&Temp_Buf[0], + data.object_property, + data.array_index, &error_class, &error_code); + if (len >= 0) { + /* encode the APDU portion of the packet */ + data.application_data = &Temp_Buf[0]; + data.application_data_len = len; + /* FIXME: probably need a length limitation sent with encode */ + pdu_len += + rp_ack_encode_apdu(&Handler_Transmit_Buffer + [pdu_len], service_data->invoke_id, &data); + send = true; + } else + error = true; + } else + error = true; + break; + default: + error = true; + break; + } + } + if (error) { + pdu_len += bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, + SERVICE_CONFIRMED_READ_PROPERTY, error_class, error_code); + send = true; + } + if (send) { + bytes_sent = datalink_send_pdu(src, /* destination address */ + &Handler_Transmit_Buffer[0], pdu_len); /* number of bytes of data */ + } + + return; +} -volatile struct mstp_port_struct_t MSTP_Port; /* port data */ -static uint8_t MSTP_MAC_Address = 0x05; /* local MAC address */ /**************************************************************************** * DESCRIPTION: Handles our calling our module level milisecond counters @@ -48,34 +140,56 @@ static void Check_Timer_Milliseconds(void) { /* We might have missed some so keep doing it until we have got them all */ while (Milliseconds) { - MSTP_Millisecond_Timer(&MSTP_Port); + dlmstp_millisecond_timer(); Milliseconds--; } } - void main(void) { - init_hardware(); - RS485_Initialize(); - MSTP_Init(&MSTP_Port, MSTP_MAC_Address); + unsigned timeout = 100; /* milliseconds */ + uint16_t pdu_len = 0; + + /* we need to handle who-is + to support dynamic device binding to us */ + apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, + handler_who_is); + /* set the handler for all the services we don't implement + It is required to send the proper reject message... */ + apdu_set_unrecognized_service_handler_handler + (handler_unrecognized_service); + /* we must implement read property - it's required! */ + apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, + handler_read_property); + /* handle communication so we can shutup when asked */ + apdu_set_confirmed_handler + (SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, + handler_device_communication_control); + + Device_Set_Object_Instance_Number(5); + dlmstp_set_my_address(0x05); + dlmstp_init(); + + init_hardware(); + + /* broadcast an I-Am on startup */ + iam_send(&Handler_Transmit_Buffer[0]); /* loop forever */ for (;;) { WATCHDOG_TIMER(); /* input */ Check_Timer_Milliseconds(); - /* note: also called by RS-485 Receive ISR */ - RS485_Check_UART_Data(&MSTP_Port); - MSTP_Receive_Frame_FSM(&MSTP_Port); + dlmstp_task(); + pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout); /* process */ - + if (pdu_len) { + npdu_handler(&src, &Rx_Buf[0], pdu_len); + } /* output */ - RS485_Process_Tx_Message(); - MSTP_Master_Node_FSM(&MSTP_Port); } diff --git a/bacnet-stack/tsm.c b/bacnet-stack/tsm.c index 6f765688..bd523851 100644 --- a/bacnet-stack/tsm.c +++ b/bacnet-stack/tsm.c @@ -57,7 +57,7 @@ /* declare space for the TSM transactions, and set it up in the init. */ /* table rules: an Invoke ID = 0 is an unused spot in the table */ -static BACNET_TSM_DATA TSM_List[MAX_TSM_TRANSACTIONS] = { {0} }; +static BACNET_TSM_DATA TSM_List[MAX_TSM_TRANSACTIONS]; /* returns MAX_TSM_TRANSACTIONS if not found */ static uint8_t tsm_find_invokeID_index(uint8_t invokeID)