|
|
@@ -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;
|
|
|
}
|