1 /*
2  * Copyright (C) 2019-2020 Alibaba Group Holding Limited
3  */
4 
5 #include <string.h>
6 
7 //#include <aos/osal_debug.h>
8 #include <aos/kernel.h>
9 
10 #include "internal.h"
11 
12 #define TAG "uSrv"
13 
14 
uservice_lock(uservice_t * srv)15 void uservice_lock(uservice_t *srv)
16 {
17     aos_assert(srv);
18     if (srv->task)
19         TASK_LOCK(srv->task);
20 }
21 
uservice_unlock(uservice_t * srv)22 void uservice_unlock(uservice_t *srv)
23 {
24     aos_assert(srv);
25     if (srv->task)
26         TASK_UNLOCK(srv->task);
27 }
28 
uservice_call(uservice_t * srv,rpc_t * rpc)29 int uservice_call(uservice_t *srv, rpc_t *rpc)
30 {
31     aos_assert(srv);
32     aos_assert(srv->task);
33 
34     rpc->srv = srv;
35 
36 #ifdef CONFIG_DEBUG
37     if(rpc->data && rpc->data->timeout_ms != 0) {
38         aos_assert(aos_task_self() != srv->task->task);
39     }
40 #endif
41 
42     int count = 10;
43     while (count--) {
44         if (aos_queue_send(&srv->task->queue, rpc, sizeof(rpc_t)) == 0) {
45             return rpc_wait(rpc);
46         } else {
47             if ( count == 1) {
48                 printf("uService %s queue full,send id:%d cur id: %d", srv->name,rpc->cmd_id, srv->task->current_rpc->cmd_id);
49             }
50             //if (!aos_irq_context())
51                 aos_msleep(100);
52         }
53     }
54 
55     return -1;
56 }
57 
uservice_call_sync(uservice_t * srv,int cmd,void * param,void * resp,size_t size)58 int uservice_call_sync(uservice_t *srv, int cmd, void *param, void *resp, size_t size)
59 {
60     aos_assert(srv);
61 
62     rpc_t rpc;
63     int ret;
64 
65     ret = rpc_init(&rpc, cmd, AOS_WAIT_FOREVER);
66 
67     if (ret < 0)
68         return ret;
69 
70     if (param)
71         rpc_put_point(&rpc, param);
72 
73     ret = uservice_call(srv, &rpc);
74 
75     if (resp != NULL && size > 0 && ret == 0) {
76         int count;
77         void *data = rpc_get_buffer(&rpc, &count);
78         aos_assert(count == size && data != NULL);
79         if (data)
80             memcpy(resp, data, size);
81     }
82 
83     rpc_deinit(&rpc);
84 
85     return ret;
86 }
87 
uservice_call_async(uservice_t * srv,int cmd,void * param,size_t param_size)88 int uservice_call_async(uservice_t *srv, int cmd, void *param, size_t param_size)
89 {
90     aos_assert(srv);
91 
92     rpc_t rpc;
93     int ret;
94 
95     ret = rpc_init(&rpc, cmd, 0);
96 
97     if (ret == 0) {
98         if (param && param_size > 0)
99             rpc_put_buffer(&rpc, param, param_size);
100 
101         ret = uservice_call(srv, &rpc);
102         rpc_deinit(&rpc);
103     }
104 
105     return ret;
106 }
107 
uservice_new(const char * name,process_t process_rpc,void * context)108 uservice_t *uservice_new(const char *name, process_t process_rpc, void *context)
109 {
110     aos_assert(process_rpc && name);
111     uservice_t *srv = aos_zalloc(sizeof(uservice_t));
112 
113     if (srv == NULL)
114         return NULL;
115 
116     srv->name        = name;
117     srv->context     = context;
118     srv->process_rpc = process_rpc;
119 
120     return srv;
121 }
122 
uservice_destroy(uservice_t * srv)123 void uservice_destroy(uservice_t *srv)
124 {
125     aos_assert(srv);
126 
127     aos_free(srv);
128 }
129 
uservice_process(void * context,rpc_t * rpc,const rpc_process_t rpcs[])130 int uservice_process(void *context, rpc_t *rpc, const rpc_process_t rpcs[])
131 {
132     for (int i = 0; rpcs[i].process != NULL; i++) {
133         if (rpcs[i].cmd_id == rpc->cmd_id) {
134             if (rpcs[i].process(context, rpc) >= 0)
135                 rpc_reply(rpc);
136             return 0;
137         }
138     }
139 
140     return -1;
141 }
142 
uservice_event_process(uint32_t event_id,const void * data,void * context)143 static void uservice_event_process(uint32_t event_id, const void *data, void *context)
144 {
145     uservice_t *srv = (uservice_t*)context;
146     rpc_t rpc;
147 
148     aos_assert(srv);
149 
150     if (rpc_init(&rpc, event_id, 0) == 0) {
151         rpc_put_point(&rpc, data);
152         uservice_call(srv, &rpc);
153         rpc_deinit(&rpc);
154     }
155 }
156 
uservice_subscribe(uservice_t * srv,uint32_t event_id)157 void uservice_subscribe(uservice_t *srv, uint32_t event_id)
158 {
159     aos_assert(srv);
160     event_subscribe(event_id, uservice_event_process, srv);
161 }
162