1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 
5 #include "aiagent_engine.h"
6 #include "py/builtin.h"
7 #include "py/mperrno.h"
8 #include "py/obj.h"
9 #include "py/runtime.h"
10 #include "ulog/ulog.h"
11 
12 #define LOG_TAG "MOD_AIAGENT"
13 
14 extern const mp_obj_type_t aiagent_type;
15 
16 #define AIAGENT_CHECK_PARAMS()                                     \
17     aiagent_obj_t *self = (aiagent_obj_t *)MP_OBJ_TO_PTR(self_in); \
18     do {                                                           \
19         if (self == NULL || self->engine_obj == NULL) {            \
20             mp_raise_OSError(EINVAL);                              \
21             return mp_const_none;                                  \
22         }                                                          \
23     } while (0)
24 
25 // this is the actual C-structure for our new object
26 typedef struct {
27     // base represents some basic information, like type
28     mp_obj_base_t base;
29 
30     // a member created by us
31     char *modName;
32     char *engine_name;
33     aiagent_engine_t *engine_obj;
34     mp_obj_t callback;
35 } aiagent_obj_t;
36 
37 static aiagent_obj_t *aiagent_obj = NULL;
38 
aiagent_new(const mp_obj_type_t * type,size_t n_args,size_t n_kw,const mp_obj_t * args)39 STATIC mp_obj_t aiagent_new(const mp_obj_type_t *type, size_t n_args,
40                             size_t n_kw, const mp_obj_t *args)
41 {
42     aiagent_obj = m_new_obj(aiagent_obj_t);
43     if (!aiagent_obj) {
44         mp_raise_OSError(ENOMEM);
45         return mp_const_none;
46     }
47 
48     memset(aiagent_obj, 0, sizeof(aiagent_obj));
49 
50     aiagent_obj->base.type = &aiagent_type;
51     aiagent_obj->modName = "aiagent";
52     aiagent_obj->engine_name = (char *)mp_obj_str_get_str(args[0]);
53     printf("aiagent_obj->engine_name: %s\n", aiagent_obj->engine_name);
54     aiagent_obj->engine_obj = NULL;
55 
56     return MP_OBJ_FROM_PTR(aiagent_obj);
57 }
58 
aiagent_print(const mp_print_t * print,mp_obj_t self_in,mp_print_kind_t kind)59 void aiagent_print(const mp_print_t *print, mp_obj_t self_in,
60                    mp_print_kind_t kind)
61 {
62     aiagent_obj_t *self = MP_OBJ_TO_PTR(self_in);
63     mp_printf(print, "modName(%s)", self->modName);
64 }
65 
aiagent_init(mp_obj_t self_in)66 STATIC mp_obj_t aiagent_init(mp_obj_t self_in)
67 {
68     aiagent_obj_t *self = (aiagent_obj_t *)MP_OBJ_TO_PTR(self_in);
69     if (self == NULL) {
70         LOGE(LOG_TAG, "aiagent_obj_t NULL");
71         return mp_const_none;
72     }
73 
74     if (self->engine_obj == NULL) {
75         self->engine_obj = aiagent_engine_init(self->engine_name);
76         if (self->engine_obj == NULL) {
77             LOGE(LOG_TAG, "create aiagent engine failed !\n");
78         }
79     }
80     return mp_const_none;
81 }
82 
83 STATIC MP_DEFINE_CONST_FUN_OBJ_1(aiagent_obj_init, aiagent_init);
84 
aiagent_uninit(mp_obj_t self_in)85 STATIC mp_obj_t aiagent_uninit(mp_obj_t self_in)
86 {
87     AIAGENT_CHECK_PARAMS();
88 
89     int status = -1;
90     if (self->engine_obj != NULL) {
91         aiagent_engine_uninit();
92         self->engine_obj = NULL;
93     }
94     self->callback = NULL;
95     return mp_const_none;
96 }
97 
98 STATIC MP_DEFINE_CONST_FUN_OBJ_1(aiagent_obj_uninit, aiagent_uninit);
99 
aiagent_config(mp_obj_t self_in,const mp_obj_t channel_in)100 STATIC mp_obj_t aiagent_config(mp_obj_t self_in, const mp_obj_t channel_in)
101 {
102     int32_t ret;
103 
104     AIAGENT_CHECK_PARAMS();
105 
106     ai_config_t config;
107     config.channel = mp_obj_get_int(channel_in);
108     self->engine_obj->config = (ai_config_t *)&config;
109     self->engine_obj->ai_engine_config(self->engine_obj);
110 
111     return mp_const_none;
112 }
113 
114 STATIC MP_DEFINE_CONST_FUN_OBJ_2(aiagent_obj_config, aiagent_config);
115 
aiagent_python_cb(ai_result_t * result)116 STATIC int aiagent_python_cb(ai_result_t *result)
117 {
118     /*TODO, need to optimize for callback*/
119     if (aiagent_obj && (aiagent_obj->callback != mp_const_none)) {
120         callback_to_python(aiagent_obj->callback, mp_const_none);
121     }
122     return 0;
123 }
124 
aiagent_infer(size_t n_args,const mp_obj_t * args)125 STATIC mp_obj_t aiagent_infer(size_t n_args, const mp_obj_t *args)
126 {
127     int32_t ret;
128 
129     if (n_args < 4) {
130         LOGE(LOG_TAG, "%s: args num is illegal :n_args = %d;\n", __func__,
131              n_args);
132         return mp_const_none;
133     }
134 
135     mp_obj_t self_in = args[0];
136     AIAGENT_CHECK_PARAMS();
137     self->callback =
138         (mp_obj_get_type(args[3]) == &mp_type_NoneType) ? NULL : args[3];
139     self->engine_obj->src1 =
140         mp_obj_is_str(args[1]) ? (char *)mp_obj_str_get_str(args[1]) : NULL;
141     self->engine_obj->src1 =
142         mp_obj_is_str(args[2]) ? (char *)mp_obj_str_get_str(args[2]) : NULL;
143     self->engine_obj->callback = aiagent_python_cb;
144 
145     ret = self->engine_obj->ai_engine_model_infer(self->engine_obj);
146 
147     return mp_obj_new_int(ret);
148 }
149 
150 STATIC MP_DEFINE_CONST_FUN_OBJ_VAR(aiagent_obj_model_infer, 4, aiagent_infer);
151 
152 STATIC const mp_rom_map_elem_t aiagent_locals_dict_table[] = {
153     { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&aiagent_obj_init) },
154     { MP_ROM_QSTR(MP_QSTR_uninit), MP_ROM_PTR(&aiagent_obj_uninit) },
155     { MP_ROM_QSTR(MP_QSTR_infer), MP_ROM_PTR(&aiagent_obj_model_infer) },
156     { MP_ROM_QSTR(MP_QSTR_config), MP_ROM_PTR(&aiagent_obj_config) },
157     { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&aiagent_obj_uninit) },
158 };
159 
160 STATIC MP_DEFINE_CONST_DICT(aiagent_locals_dict, aiagent_locals_dict_table);
161 
162 const mp_obj_type_t aiagent_type = {
163     .base = { &mp_type_type },
164     .name = MP_QSTR_AIAgent,
165     .print = aiagent_print,
166     .make_new = aiagent_new,
167     .locals_dict = (mp_obj_dict_t *)&aiagent_locals_dict,
168 };
169