@@ -1693,6 +1693,42 @@ static bool rx_filter_configure(canard_t* const self)
16931693 return ok ;
16941694}
16951695
1696+ // Common subscribe logic: validate, initialize, insert into tree, mark filters dirty.
1697+ static bool rx_subscribe (canard_t * const self ,
1698+ canard_subscription_t * const subscription ,
1699+ const canard_kind_t kind ,
1700+ const uint16_t port_id ,
1701+ const uint16_t crc_seed ,
1702+ const size_t extent ,
1703+ const canard_us_t transfer_id_timeout ,
1704+ const canard_subscription_vtable_t * const vtable )
1705+ {
1706+ bool ok = (self != NULL ) && (subscription != NULL ) && (vtable != NULL ) && (vtable -> on_message != NULL ) &&
1707+ (transfer_id_timeout >= 0 );
1708+ if (ok ) {
1709+ (void )memset (subscription , 0 , sizeof (* subscription ));
1710+ subscription -> transfer_id_timeout = transfer_id_timeout ;
1711+ subscription -> extent = extent ;
1712+ subscription -> port_id = port_id ;
1713+ subscription -> crc_seed = crc_seed ;
1714+ subscription -> kind = kind ;
1715+ subscription -> owner = self ;
1716+ subscription -> vtable = vtable ;
1717+ const canard_tree_t * const existing = cavl2_find_or_insert (& self -> rx .subscriptions [kind ],
1718+ & subscription -> port_id ,
1719+ rx_subscription_cavl_compare ,
1720+ & subscription -> index_port_id ,
1721+ cavl2_trivial_factory );
1722+ if (existing != & subscription -> index_port_id ) {
1723+ (void )memset (subscription , 0 , sizeof (* subscription )); // Undo partial init on duplicate.
1724+ ok = false;
1725+ } else {
1726+ self -> rx .filters_dirty = true;
1727+ }
1728+ }
1729+ return ok ;
1730+ }
1731+
16961732// --------------------------------------------- MISC ---------------------------------------------
16971733
16981734static void node_id_occupancy_reset (canard_t * const self )
@@ -1896,3 +1932,54 @@ uint16_t canard_0v1_crc_seed_from_data_type_signature(const uint64_t data_type_s
18961932 }
18971933 return crc ;
18981934}
1935+
1936+ bool canard_subscribe (canard_t * const self ,
1937+ canard_subscription_t * const subscription ,
1938+ const uint16_t subject_id ,
1939+ const bool rev_1v0 ,
1940+ const size_t extent ,
1941+ const canard_us_t transfer_id_timeout ,
1942+ const canard_subscription_vtable_t * const vtable )
1943+ {
1944+ return (!rev_1v0 || (subject_id <= CANARD_SUBJECT_ID_MAX_1v0 )) &&
1945+ rx_subscribe (self ,
1946+ subscription ,
1947+ rev_1v0 ? canard_kind_1v0_message : canard_kind_1v1_message ,
1948+ subject_id ,
1949+ CRC_INITIAL ,
1950+ extent ,
1951+ transfer_id_timeout ,
1952+ vtable );
1953+ }
1954+
1955+ bool canard_subscribe_request (canard_t * const self ,
1956+ canard_subscription_t * const subscription ,
1957+ const uint16_t service_id ,
1958+ const size_t extent ,
1959+ const canard_us_t transfer_id_timeout ,
1960+ const canard_subscription_vtable_t * const vtable )
1961+ {
1962+ return (service_id <= CANARD_SERVICE_ID_MAX ) &&
1963+ rx_subscribe (
1964+ self , subscription , canard_kind_1v0_request , service_id , CRC_INITIAL , extent , transfer_id_timeout , vtable );
1965+ }
1966+
1967+ bool canard_subscribe_response (canard_t * const self ,
1968+ canard_subscription_t * const subscription ,
1969+ const uint16_t service_id ,
1970+ const size_t extent ,
1971+ const canard_subscription_vtable_t * const vtable )
1972+ {
1973+ return (service_id <= CANARD_SERVICE_ID_MAX ) &&
1974+ rx_subscribe (self , subscription , canard_kind_1v0_response , service_id , CRC_INITIAL , extent , 0 , vtable );
1975+ }
1976+
1977+ void canard_unsubscribe (canard_t * const self , canard_subscription_t * const subscription )
1978+ {
1979+ CANARD_ASSERT ((self != NULL ) && (subscription != NULL ) && (subscription -> owner == self ));
1980+ while (subscription -> sessions != NULL ) {
1981+ rx_session_destroy ((rx_session_t * )(void * )cavl2_min (subscription -> sessions ));
1982+ }
1983+ cavl2_remove (& self -> rx .subscriptions [subscription -> kind ], & subscription -> index_port_id );
1984+ self -> rx .filters_dirty = true;
1985+ }
0 commit comments