@@ -484,6 +484,71 @@ int engine_observe_attribute_list_get(sys_slist_t *path_list, struct notificatio
484
484
return 0 ;
485
485
}
486
486
487
+ static int resource_value_as_double (const struct lwm2m_obj_path * path ,
488
+ double * value )
489
+ {
490
+ struct lwm2m_engine_obj_field * obj_field ;
491
+ union {
492
+ int64_t s64 ;
493
+ int32_t s32 ;
494
+ int16_t s16 ;
495
+ int8_t s8 ;
496
+ uint32_t u32 ;
497
+ uint16_t u16 ;
498
+ uint8_t u8 ;
499
+ } temp_buf = { 0 };
500
+ int ret ;
501
+
502
+ lwm2m_registry_lock ();
503
+
504
+ ret = path_to_objs (path , NULL , & obj_field , NULL , NULL );
505
+ if (ret < 0 || obj_field == NULL ) {
506
+ lwm2m_registry_unlock ();
507
+ return - ENOENT ;
508
+ }
509
+
510
+ switch (obj_field -> data_type ) {
511
+ case LWM2M_RES_TYPE_U32 :
512
+ ret = lwm2m_get_u32 (path , & temp_buf .u32 );
513
+ * value = (double )temp_buf .u32 ;
514
+ break ;
515
+ case LWM2M_RES_TYPE_U16 :
516
+ ret = lwm2m_get_u16 (path , & temp_buf .u16 );
517
+ * value = (double )temp_buf .u16 ;
518
+ break ;
519
+ case LWM2M_RES_TYPE_U8 :
520
+ ret = lwm2m_get_u8 (path , & temp_buf .u8 );
521
+ * value = (double )temp_buf .u8 ;
522
+ break ;
523
+ case LWM2M_RES_TYPE_S64 :
524
+ ret = lwm2m_get_s64 (path , & temp_buf .s64 );
525
+ * value = (double )temp_buf .s64 ;
526
+ break ;
527
+ case LWM2M_RES_TYPE_S32 :
528
+ ret = lwm2m_get_s32 (path , & temp_buf .s32 );
529
+ * value = (double )temp_buf .s32 ;
530
+ break ;
531
+ case LWM2M_RES_TYPE_S16 :
532
+ ret = lwm2m_get_s16 (path , & temp_buf .s16 );
533
+ * value = (double )temp_buf .s16 ;
534
+ break ;
535
+ case LWM2M_RES_TYPE_S8 :
536
+ ret = lwm2m_get_s8 (path , & temp_buf .s8 );
537
+ * value = (double )temp_buf .s8 ;
538
+ break ;
539
+ case LWM2M_RES_TYPE_FLOAT :
540
+ ret = lwm2m_get_f64 (path , value );
541
+ break ;
542
+ default :
543
+ ret = - ENOTSUP ;
544
+ break ;
545
+ }
546
+
547
+ lwm2m_registry_unlock ();
548
+
549
+ return ret ;
550
+ }
551
+
487
552
int lwm2m_notify_observer_path (const struct lwm2m_obj_path * path )
488
553
{
489
554
struct observe_node * obs ;
@@ -757,6 +822,8 @@ static int engine_add_observer(struct lwm2m_message *msg, const uint8_t *token,
757
822
msg -> path .obj_inst_id , msg -> path .res_id , msg -> path .level ,
758
823
lwm2m_sprint_ip_addr (& msg -> ctx -> remote_addr ));
759
824
825
+ lwm2m_engine_observer_refresh_notified_values (obs );
826
+
760
827
return 0 ;
761
828
}
762
829
@@ -772,6 +839,8 @@ static int engine_add_observer(struct lwm2m_message *msg, const uint8_t *token,
772
839
}
773
840
774
841
engine_observe_node_init (obs , token , msg -> ctx , tkl , format , attrs .pmax );
842
+ lwm2m_engine_observer_refresh_notified_values (obs );
843
+
775
844
return 0 ;
776
845
}
777
846
@@ -845,6 +914,8 @@ static int engine_add_composite_observer(struct lwm2m_message *msg, const uint8_
845
914
LOG_DBG ("OBSERVER Composite DUPLICATE [%s]" ,
846
915
lwm2m_sprint_ip_addr (& msg -> ctx -> remote_addr ));
847
916
917
+ lwm2m_engine_observer_refresh_notified_values (obs );
918
+
848
919
return do_composite_read_op_for_parsed_list (msg , format , & lwm2m_path_list );
849
920
}
850
921
@@ -858,6 +929,8 @@ static int engine_add_composite_observer(struct lwm2m_message *msg, const uint8_
858
929
return - ENOMEM ;
859
930
}
860
931
engine_observe_node_init (obs , token , msg -> ctx , tkl , format , attrs .pmax );
932
+ lwm2m_engine_observer_refresh_notified_values (obs );
933
+
861
934
return do_composite_read_op_for_parsed_list (msg , format , & lwm2m_path_list );
862
935
}
863
936
@@ -1822,3 +1895,134 @@ void lwm2m_engine_clear_duplicate_path(sys_slist_t *lwm2m_path_list, sys_slist_t
1822
1895
}
1823
1896
}
1824
1897
}
1898
+
1899
+ static void update_resource_instance_notified_value (
1900
+ const struct lwm2m_obj_path * path ,
1901
+ const struct lwm2m_engine_res_inst * ref )
1902
+ {
1903
+ struct lwm2m_notify_value_register * last_notified ;
1904
+ double new_value ;
1905
+ int ret ;
1906
+
1907
+ last_notified = notify_value_reg_get (ref );
1908
+ if (last_notified == NULL ) {
1909
+ return ;
1910
+ }
1911
+
1912
+ ret = resource_value_as_double (path , & new_value );
1913
+ if (ret < 0 ) {
1914
+ return ;
1915
+ }
1916
+
1917
+ last_notified -> value = new_value ;
1918
+ last_notified -> notified = true;
1919
+ }
1920
+
1921
+ static void update_resource_notified_value (const struct lwm2m_obj_path * path ,
1922
+ const struct lwm2m_engine_res * res )
1923
+ {
1924
+ struct lwm2m_obj_path res_inst_path = {
1925
+ .level = LWM2M_PATH_LEVEL_RESOURCE_INST ,
1926
+ .obj_id = path -> obj_id ,
1927
+ .obj_inst_id = path -> obj_inst_id ,
1928
+ .res_id = path -> res_id ,
1929
+ };
1930
+ struct lwm2m_engine_res_inst * res_inst ;
1931
+
1932
+ if (!is_resource_numerical (path )) {
1933
+ return ;
1934
+ }
1935
+
1936
+ for (int i = 0 ; i < res -> res_inst_count ; i ++ ) {
1937
+ res_inst = & res -> res_instances [i ];
1938
+ res_inst_path .res_inst_id = res_inst -> res_inst_id ;
1939
+
1940
+ if (res_inst -> res_inst_id == RES_INSTANCE_NOT_CREATED ) {
1941
+ continue ;
1942
+ }
1943
+
1944
+ update_resource_instance_notified_value (& res_inst_path , res_inst );
1945
+ }
1946
+ }
1947
+
1948
+ static void update_object_instance_notified_values (
1949
+ const struct lwm2m_obj_path * path ,
1950
+ const struct lwm2m_engine_obj_inst * obj_inst )
1951
+ {
1952
+ struct lwm2m_obj_path res_path = {
1953
+ .level = LWM2M_PATH_LEVEL_RESOURCE ,
1954
+ .obj_id = path -> obj_id ,
1955
+ .obj_inst_id = path -> obj_inst_id ,
1956
+ };
1957
+ struct lwm2m_engine_res * res ;
1958
+
1959
+ for (int i = 0 ; i < obj_inst -> resource_count ; i ++ ) {
1960
+ res = & obj_inst -> resources [i ];
1961
+ res_path .res_id = res -> res_id ;
1962
+
1963
+ update_resource_notified_value (& res_path , res );
1964
+ }
1965
+ }
1966
+
1967
+ static void update_object_notified_values (const struct lwm2m_obj_path * path ,
1968
+ const struct lwm2m_engine_obj * obj )
1969
+ {
1970
+ struct lwm2m_engine_obj_inst * obj_inst = next_engine_obj_inst (obj -> obj_id , -1 );
1971
+ struct lwm2m_obj_path obj_inst_path = {
1972
+ .level = LWM2M_PATH_LEVEL_OBJECT_INST ,
1973
+ .obj_id = path -> obj_id ,
1974
+ };
1975
+
1976
+ if (obj_inst == NULL ) {
1977
+ return ;
1978
+ }
1979
+
1980
+ for (int i = 0 ; i < obj -> instance_count ; i ++ ) {
1981
+ obj_inst_path .obj_inst_id = obj_inst -> obj_inst_id ;
1982
+
1983
+ update_object_instance_notified_values (& obj_inst_path , obj_inst );
1984
+
1985
+ obj_inst = next_engine_obj_inst (obj -> obj_id , obj_inst -> obj_inst_id );
1986
+ if (obj_inst == NULL ) {
1987
+ break ;
1988
+ }
1989
+ }
1990
+ }
1991
+
1992
+ void lwm2m_engine_observer_refresh_notified_values (struct observe_node * obs )
1993
+ {
1994
+ struct lwm2m_obj_path_list * tmp ;
1995
+ struct lwm2m_obj_path * obs_path ;
1996
+ void * ref ;
1997
+ int ret ;
1998
+
1999
+ lwm2m_registry_lock ();
2000
+
2001
+ SYS_SLIST_FOR_EACH_CONTAINER (& obs -> path_list , tmp , node ) {
2002
+ obs_path = & tmp -> path ;
2003
+
2004
+ ret = lwm2m_get_path_reference_ptr (NULL , & tmp -> path , & ref );
2005
+ if (ret < 0 ) {
2006
+ continue ;
2007
+ }
2008
+
2009
+ switch (obs_path -> level ) {
2010
+ case LWM2M_PATH_LEVEL_RESOURCE_INST :
2011
+ update_resource_instance_notified_value (obs_path , ref );
2012
+ break ;
2013
+ case LWM2M_PATH_LEVEL_RESOURCE :
2014
+ update_resource_notified_value (obs_path , ref );
2015
+ break ;
2016
+ case LWM2M_PATH_LEVEL_OBJECT_INST :
2017
+ update_object_instance_notified_values (obs_path , ref );
2018
+ break ;
2019
+ case LWM2M_PATH_LEVEL_OBJECT :
2020
+ update_object_notified_values (obs_path , ref );
2021
+ break ;
2022
+ default :
2023
+ break ;
2024
+ }
2025
+ }
2026
+
2027
+ lwm2m_registry_unlock ();
2028
+ }
0 commit comments