Просмотр исходного кода

f407 snmp 获取设备类型,和电量信息

liyi 1 год назад
Родитель
Сommit
94fa97a961
3 измененных файлов с 440 добавлено и 13 удалено
  1. 2 1
      f407/applications/main.c
  2. 422 12
      f407/applications/snmp.c
  3. 16 0
      f407/applications/snmp.h

+ 2 - 1
f407/applications/main.c

@@ -13,6 +13,7 @@
 #include "cfg.h"
 #include "paras.h"
 #include "cascade.h"
+#include "snmp.h"
 
 //https://embedded-rd.blog.csdn.net/article/details/109643188
 
@@ -97,7 +98,7 @@ static int user_init(void)
 {
     paras_data_t *p=paras_get();
     modbus_data_t *cas=&p->cas;
-    
+    snmp2_init();
     power_init();
     cascade_init();
     web_init();

+ 422 - 12
f407/applications/snmp.c

@@ -3,6 +3,402 @@
 #include "lwip/apps/snmp_mib2.h"
 #include "lwip/apps/snmp_opts.h"
 #include "lwip/apps/snmpv3.h" // 如果使用 SNMP v3
+#include "lwip/apps/snmp_opts.h"
+#include "lwip/apps/snmp_core.h"
+#include "lwip/apps/snmp_table.h"
+#include "lwip/apps/snmp_scalar.h"
+#include "string.h"
+
+
+
+
+
+
+#define SNMP_SMARTPDU_OID 										{1,3,6,1,4,1,2024}
+#define SNMP_SMARTPDU_DEVICE_OID							{1,3,6,1,4,1,2024,1}
+#define SNMP_SMARTPDU_CHANNEL_TABLE           {1,3,6,1,4,1,2024,1,3,9}
+
+typedef struct 
+{
+	uint8_t sysdescr[10];
+	uint8_t syscontact[5];
+	uint8_t sysname[3];
+	uint8_t syslocation[3];
+	struct snmp_obj_id device_enterprose_oid;
+//	char *id_manifacture;
+//	char *id_device;
+//	char *id_sn;
+//	char *id_version;	
+}snmp_smarpdu_t;
+
+static snmp_smarpdu_t snmp_smart={
+		.sysdescr={"Smart_pdu"},
+		.syscontact={"KyKy"},
+		.sysname={"Rt"},
+		.syslocation={"CN"},
+		.device_enterprose_oid={
+			.len = 7,
+			.id = SNMP_SMARTPDU_OID,
+		},
+//		.id_manifacture = "Gowone Industry",
+//		.id_device = "Smart_PDU",
+//		.id_sn = "SN123465",
+//		.id_version = "v1.0.0.0",
+};
+
+
+
+static s16_t sysinfo_get_value(const struct snmp_scalar_array_node_def *node, void *value)
+{
+    char *var = NULL;
+    s16_t var_len;
+		char buff[100]= {0};
+		switch(node->oid)
+		{
+			case 1:
+			{
+				sprintf(buff,"%d",0);
+			}
+			break;
+			case 2:
+			{
+					sprintf(buff,"%s","smart_pdu");
+			}
+			break;
+			case 3:
+			{
+					sprintf(buff,"%s","DC");			
+			}
+			break;
+			case 4:
+			{
+					sprintf(buff,"%s","SN1235");					
+			}
+			break;
+			case 5:
+			{
+				sprintf(buff,"%d",12);		
+			}				
+			break;
+			case 6:
+			{
+				sprintf(buff,"%d",7);	
+			}
+			break;
+			default:
+			{
+				  LOGE("sysinfo_get_value(): unknown id: %d\n", node->oid);
+					return 0;
+			}
+
+		}
+		var_len = strlen(buff);
+		memcpy(value, buff, var_len);
+		return var_len;
+}
+
+
+#define POWER_VALUE 4
+
+typedef struct power_data{
+	uint8_t 						id;
+	char  	 *				name;
+	uint8_t         status;
+	float  						v;
+	float             i;
+	float 						f;
+	float             c;
+	float             fa;
+	float             p;
+	float             r_p;
+	float             a_p;
+}p_data_t;
+
+
+
+static p_data_t p_data[POWER_VALUE]={
+	{
+		.id = 1,
+		.name = "smart_pdu",
+		.status = 1,
+		.v=220.0,
+		.i = 15.3,
+		.f = 48.95,
+		.c = 20.14,
+		.fa = 0.89,
+		.p = 480.12,
+		.r_p = 520.45,
+		.a_p = 600.12,
+	},
+		{
+		.id = 2,
+		.name = "smart_pdu",
+		.status = 1,
+		.v=218.0,
+		.i = 15.3,
+		.f = 49.95,
+		.c = 20.14,
+		.fa = 0.89,
+		.p = 480.12,
+		.r_p = 520.45,
+		.a_p = 600.12,
+	},
+			{
+		.id = 3,
+		.name = "smart_pdu",
+		.status = 1,
+		.v=219.0,
+		.i = 9.3,
+		.f = 48.95,
+		.c = 20.14,
+		.fa = 0.89,
+		.p = 100.12,
+		.r_p = 230.45,
+		.a_p = 460.12,
+	},
+	{
+		.id = 4,
+		.name = "smart_pdu",
+		.status = 0,
+		.v=220.0,
+		.i = 15.3,
+		.f = 48.95,
+		.c = 20.14,
+		.fa = 0.89,
+		.p = 480.12,
+		.r_p = 520.45,
+		.a_p = 600.12,
+	},
+};
+
+
+
+static const struct snmp_oid_range th_table_oid_ranges[] = {
+    {1, POWER_VALUE},
+};
+
+
+static snmp_err_t power_get_instance(const u32_t *column, const u32_t *row_oid, u8_t row_oid_len, struct snmp_node_instance *cell_instance)
+{
+	if (!snmp_oid_in_range(row_oid, row_oid_len, th_table_oid_ranges, LWIP_ARRAYSIZE(th_table_oid_ranges)))
+        return SNMP_ERR_NOSUCHINSTANCE;
+	cell_instance->reference.u32 = row_oid[0];
+
+	return SNMP_ERR_NOERROR;
+}
+
+
+static snmp_err_t power_get_next_instance(const u32_t *column, struct snmp_obj_id *row_oid, struct snmp_node_instance *cell_instance)
+{
+    u8_t i = 0;
+    struct snmp_next_oid_state state;
+    u32_t next_oid = 0;
+
+    snmp_next_oid_init(&state, row_oid->id, row_oid->len, &next_oid, 1);
+    for (i = 0; i < POWER_VALUE; i++)
+    {
+        u32_t test_oid = i + 1;
+        snmp_next_oid_check(&state, &test_oid, 1, NULL);
+    }
+
+    if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS)
+    {
+        snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len);
+        cell_instance->reference.u32 = *state.next_oid; /* 下个节点行OID */
+        return SNMP_ERR_NOERROR;
+    }
+
+    return SNMP_ERR_NOSUCHINSTANCE;
+}
+
+static s16_t power_get_value(struct snmp_node_instance *instance, void *value)
+{
+    u32_t row = instance->reference.u32;
+    u32_t col = SNMP_TABLE_GET_COLUMN_FROM_OID(instance->instance_oid.id);
+    //s32_t *value_s32 = (s32_t *)value;
+
+    /* 第一列索引 */
+//    if (col == 1)
+//    {
+//        *(s32_t *)value = row;
+//        return sizeof(s32_t);
+//    } 
+//    if (col < 4)
+//         th_value[row - 1][col - 2] = row * 100 + col * 10 + rand() % 10 + th_value[row - 1][col];
+
+//    *value_s32 = p_data[row - 1][col - 2];
+		char buff[100]= {0};
+		switch (col)
+		{
+			case COLUMN_PDUCHANNELID:
+			{
+				*(s32_t *)value	= p_data[row-1].id;
+				return 4;
+			}
+				break;
+			case COLUMN_PDUCHANNELNAME:
+			{
+				sprintf(buff,"%s",p_data[row-1].name);
+			}
+				break;
+			case COLUMN_PDUCHANNELSTATUS:
+			{
+				//sprintf(buff,"%d",p_data[row].status);
+				*(s32_t *)value	= p_data[row-1].status;
+				return 4;
+			}
+				break;
+			case COLUMN_PDUCHANNELVOLTAGE:
+			{
+				sprintf(buff,"%.2f",p_data[row-1].v);
+			}
+				break;
+			case COLUMN_PDUCHANNELCURRENT:
+			{
+				sprintf(buff,"%.2f",p_data[row-1].i);
+			}
+				break;
+			case COLUMN_PDUCHANNELFREQUENCY:
+			{
+				sprintf(buff,"%.2f",p_data[row-1].f);
+			}
+				break;
+			case COLUMN_PDUCHANNELCONSUMPTION:
+			{
+				sprintf(buff,"%.2f",p_data[row-1].c);
+			}
+				break;
+			case COLUMN_PDUCHANNELPOWERFACTOR:
+			{
+				sprintf(buff,"%.2f",p_data[row-1].fa);
+			}
+				break;
+			case COLUMN_PDUCHANNELPACTIVEPOWER:
+			{
+				sprintf(buff,"%.2f",p_data[row-1].p);
+			}
+				break;
+			case COLUMN_PDUCHANNELREACTIVEPOWER:
+			{
+				sprintf(buff,"%.2f",p_data[row-1].r_p);
+			}
+				break;
+			case COLUMN_PDUCHANNELAPPARENTPOWER:
+			{
+				sprintf(buff,"%.2f",p_data[row-1].a_p);
+			}
+				break;
+			default:
+				return 0;
+		}
+		
+		memcpy(value,buff,strlen(buff));
+		
+    return strlen(buff);
+}
+static snmp_err_t th_set_test(struct snmp_node_instance *instance, u16_t len, void *value)
+{
+	LOGD("write test\n");
+	return SNMP_ERR_NOERROR;
+}
+
+static snmp_err_t  power_set_value (struct snmp_node_instance *instance, u16_t len, void *value)
+{
+	  u32_t row = instance->reference.u32;
+    u32_t col = SNMP_TABLE_GET_COLUMN_FROM_OID(instance->instance_oid.id);
+		switch(col)
+		{
+			case  COLUMN_PDUCHANNELSTATUS:
+			{
+				p_data[row-1].status = *(uint32_t*)value;
+			}
+				break;
+			default:
+				return SNMP_ERR_NOTWRITABLE;
+		}
+		return SNMP_ERR_NOERROR;
+}
+
+
+static const struct snmp_scalar_array_node_def sysinfo_scalars_nodes[] = {
+    {1, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY}, 				/* product id  */
+    {2, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY}, 				/* product name */
+    {3, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY}, 				/* product type */
+    {4, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY}, 				/* product firmware */
+		{5, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY}, 				/* product channal number */
+		{6, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY}, 				/* product sensor number */
+		{0,0,0},
+};
+
+
+
+static const struct snmp_table_col_def power_table_channels[]={
+	{COLUMN_PDUCHANNELID,SNMP_ASN1_TYPE_INTEGER,SNMP_NODE_INSTANCE_READ_ONLY},
+	{COLUMN_PDUCHANNELNAME,SNMP_ASN1_TYPE_OCTET_STRING,SNMP_NODE_INSTANCE_READ_ONLY},
+	{COLUMN_PDUCHANNELSTATUS,SNMP_ASN1_TYPE_INTEGER,SNMP_NODE_INSTANCE_READ_ONLY},
+	{COLUMN_PDUCHANNELVOLTAGE,SNMP_ASN1_TYPE_OCTET_STRING,SNMP_NODE_INSTANCE_READ_ONLY},
+	{COLUMN_PDUCHANNELCURRENT,SNMP_ASN1_TYPE_OCTET_STRING,SNMP_NODE_INSTANCE_READ_ONLY},
+	{COLUMN_PDUCHANNELFREQUENCY,SNMP_ASN1_TYPE_OCTET_STRING,SNMP_NODE_INSTANCE_READ_ONLY},
+	{COLUMN_PDUCHANNELCONSUMPTION,SNMP_ASN1_TYPE_OCTET_STRING,SNMP_NODE_INSTANCE_READ_ONLY},
+	{COLUMN_PDUCHANNELPOWERFACTOR,SNMP_ASN1_TYPE_OCTET_STRING,SNMP_NODE_INSTANCE_READ_ONLY},
+	{COLUMN_PDUCHANNELPACTIVEPOWER,SNMP_ASN1_TYPE_OCTET_STRING,SNMP_NODE_INSTANCE_READ_ONLY},
+	{COLUMN_PDUCHANNELREACTIVEPOWER,SNMP_ASN1_TYPE_OCTET_STRING,SNMP_NODE_INSTANCE_READ_ONLY},
+	{COLUMN_PDUCHANNELAPPARENTPOWER,SNMP_ASN1_TYPE_OCTET_STRING,SNMP_NODE_INSTANCE_READ_ONLY},
+	{0,0,0},
+};
+
+
+const struct snmp_scalar_array_node sysinfo_scalars = SNMP_SCALAR_CREATE_ARRAY_NODE(1, sysinfo_scalars_nodes, sysinfo_get_value, NULL, NULL);
+static const struct snmp_table_node power_table = SNMP_TABLE_CREATE(9, power_table_channels, power_get_instance, power_get_next_instance, \
+	power_get_value, th_set_test, power_set_value);
+
+
+
+
+
+
+
+static const struct snmp_node *const power_subnodes[] = {
+    &power_table.node.node,
+};
+
+
+const struct snmp_tree_node power_treenode = SNMP_CREATE_TREE_NODE(3, power_subnodes);
+
+static const struct snmp_node *const mib2_nodes_dev[] =
+{
+    &sysinfo_scalars.node.node,
+		&power_treenode.node,
+};
+
+//static const struct snmp_node *const mib2_nodes_pw_dev[] ={
+//		&power_treenode.node,
+//};
+
+
+
+static const struct snmp_tree_node snmp_mib2_root_dev = SNMP_CREATE_TREE_NODE(1, mib2_nodes_dev);
+
+//static const struct snmp_tree_node snmp_mib2_pw_dev = SNMP_CREATE_TREE_NODE(11, mib2_nodes_pw_dev);
+
+
+
+
+static const u32_t prvmib_base_oid[] = SNMP_SMARTPDU_DEVICE_OID;
+//static const u32_t power_base_oid[] = SNMP_SMARTPDU_CHANNEL_TABLE;
+
+
+const struct snmp_mib mib2_dev = SNMP_MIB_CREATE(prvmib_base_oid, &snmp_mib2_root_dev.node);
+//const struct snmp_mib mib2_pw_dev = SNMP_MIB_CREATE(power_base_oid, &snmp_mib2_pw_dev.node);
+
+
+static const struct snmp_mib *dev_mibs[] = {&mib2, &mib2_dev};
+
+
+
+
+
+
 
 
 void netif_event_callback(struct netif *netif) {
@@ -11,22 +407,36 @@ void netif_event_callback(struct netif *netif) {
 }
 
 static void mibs_init(void) {
-    //snmp_mib2_set_syscontact("admin@example.com");
-    //snmp_mib2_set_syslocation("Basement");
-    //snmp_mib2_set_sysdescr("LwIP/SNMP Test Device", "");
-    //snmp_mib2_set_sysname("TestDevice");
+		uint16_t len = 0;
+		len= strlen((const char *)snmp_smart.sysdescr);
+    snmp_mib2_set_sysdescr(snmp_smart.sysdescr, &len);
+	
+		len= strlen((const char *)snmp_smart.syscontact);
+    snmp_mib2_set_syscontact(snmp_smart.syscontact, &len, 0);
+	
+		len= strlen((const char *)snmp_smart.sysname);
+    snmp_mib2_set_sysname(snmp_smart.sysname, &len, 0);
+	
+		len= strlen((const char *)snmp_smart.syslocation);
+    snmp_mib2_set_syslocation(snmp_smart.syslocation, &len, 0);	
+	
+	  snmp_set_device_enterprise_oid(&snmp_smart.device_enterprose_oid);
+    snmp_set_auth_traps_enabled(SNMP_AUTH_TRAPS_DISABLED);
+	
+    snmp_trap_dst_enable(0, 0);
+    //snmp_trap_dst_ip_set(0, &test_snmp_trap_ip);	
+
+    snmp_set_mibs(&dev_mibs[0], LWIP_ARRAYSIZE(dev_mibs));
+    snmp_set_community("public");
+    snmp_set_community_write("public");	
 }
 
 int snmp2_init(void)
 {
-    
-    snmp_init();
-    snmp_init_mib2();
-    //snmp_set_mibs(mibs, LWIP_ARRAYSIZE(mibs));
-    //snmp_trap_dst_enable(1, 1); // 启用SNMP陷阱
-    //snmp_set_device_enterprise_oid(device_enterprise_oid); // 设置设备的企业 OID
-    //snmp_asn1_enc_type_value(asn1Type, value); // 设置 MIB 的初始值等
-    //snmp_mib_node_add(&my_mib_node);
+	
+	mibs_init();
+  snmp_init();
+
     
     return 0;
 }

+ 16 - 0
f407/applications/snmp.h

@@ -3,6 +3,22 @@
 
 #include "datadef.h"
 
+/* column number definitions for table pduChannelTable */
+       #define COLUMN_PDUCHANNELID		1
+       #define COLUMN_PDUCHANNELNAME		2
+       #define COLUMN_PDUCHANNELSTATUS		3
+       #define COLUMN_PDUCHANNELVOLTAGE		4
+       #define COLUMN_PDUCHANNELCURRENT		5
+       #define COLUMN_PDUCHANNELFREQUENCY		6
+       #define COLUMN_PDUCHANNELCONSUMPTION		7
+       #define COLUMN_PDUCHANNELPOWERFACTOR		8
+       #define COLUMN_PDUCHANNELPACTIVEPOWER		9
+       #define COLUMN_PDUCHANNELREACTIVEPOWER		10
+       #define COLUMN_PDUCHANNELAPPARENTPOWER		11
+
+
+
+
 int snmp2_init(void);
 int snmp2_deinit(void);