~bremby/grub4helenos/main

« back to all changes in this revision

Viewing changes to uspace/lib/c/generic/inetping.c

  • Committer: Dominik Taborsky
  • Date: 2013-11-21 18:22:43 UTC
  • mfrom: (1709.15.116 main-clone)
  • Revision ID: dominik_taborsky_brembyatseznamdotcz-20131121182243-hj3h7k9oscpbxilu
mainlineĀ merge

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright (c) 2012 Jiri Svoboda
 
2
 * Copyright (c) 2013 Jiri Svoboda
 
3
 * Copyright (c) 2013 Martin Decky
3
4
 * All rights reserved.
4
5
 *
5
6
 * Redistribution and use in source and binary forms, with or without
48
49
        int rc;
49
50
 
50
51
        assert(inetping_sess == NULL);
51
 
        
 
52
 
52
53
        inetping_ev_ops = ev_ops;
53
 
        
 
54
 
54
55
        rc = loc_service_get_id(SERVICE_NAME_INETPING, &inetping_svc,
55
56
            IPC_FLAG_BLOCKING);
56
57
        if (rc != EOK)
57
58
                return ENOENT;
58
 
        
 
59
 
59
60
        inetping_sess = loc_service_connect(EXCHANGE_SERIALIZE, inetping_svc,
60
61
            IPC_FLAG_BLOCKING);
61
62
        if (inetping_sess == NULL)
62
63
                return ENOENT;
63
 
        
 
64
 
64
65
        async_exch_t *exch = async_exchange_begin(inetping_sess);
65
66
 
66
67
        rc = async_connect_to_me(exch, 0, 0, 0, inetping_cb_conn, NULL);
67
68
        async_exchange_end(exch);
68
 
        
 
69
 
69
70
        if (rc != EOK) {
70
71
                async_hangup(inetping_sess);
71
72
                inetping_sess = NULL;
72
73
                return rc;
73
74
        }
74
 
        
 
75
 
75
76
        return EOK;
76
77
}
77
78
 
78
79
int inetping_send(inetping_sdu_t *sdu)
79
80
{
80
81
        async_exch_t *exch = async_exchange_begin(inetping_sess);
81
 
        
 
82
 
82
83
        ipc_call_t answer;
83
 
        aid_t req = async_send_3(exch, INETPING_SEND, (sysarg_t) sdu->src,
84
 
            (sysarg_t) sdu->dest, sdu->seq_no, &answer);
85
 
        sysarg_t retval = async_data_write_start(exch, sdu->data, sdu->size);
86
 
        
 
84
        aid_t req = async_send_1(exch, INETPING_SEND, sdu->seq_no, &answer);
 
85
 
 
86
        int rc = async_data_write_start(exch, &sdu->src, sizeof(sdu->src));
 
87
        if (rc != EOK) {
 
88
                async_exchange_end(exch);
 
89
                async_forget(req);
 
90
                return rc;
 
91
        }
 
92
 
 
93
        rc = async_data_write_start(exch, &sdu->dest, sizeof(sdu->dest));
 
94
        if (rc != EOK) {
 
95
                async_exchange_end(exch);
 
96
                async_forget(req);
 
97
                return rc;
 
98
        }
 
99
 
 
100
        rc = async_data_write_start(exch, sdu->data, sdu->size);
 
101
 
87
102
        async_exchange_end(exch);
88
 
        
89
 
        if (retval != EOK) {
 
103
 
 
104
        if (rc != EOK) {
90
105
                async_forget(req);
91
 
                return retval;
 
106
                return rc;
92
107
        }
93
 
        
 
108
 
 
109
        sysarg_t retval;
94
110
        async_wait_for(req, &retval);
95
 
        return retval;
 
111
 
 
112
        return (int) retval;
96
113
}
97
114
 
98
 
int inetping_get_srcaddr(uint32_t remote, uint32_t *local)
 
115
int inetping_get_srcaddr(const inet_addr_t *remote, inet_addr_t *local)
99
116
{
100
117
        async_exch_t *exch = async_exchange_begin(inetping_sess);
101
 
        
102
 
        sysarg_t local_addr;
103
 
        int rc = async_req_1_1(exch, INETPING_GET_SRCADDR, (sysarg_t) remote,
104
 
            &local_addr);
105
 
        
 
118
 
 
119
        ipc_call_t answer;
 
120
        aid_t req = async_send_0(exch, INETPING_GET_SRCADDR, &answer);
 
121
 
 
122
        int rc = async_data_write_start(exch, remote, sizeof(*remote));
 
123
        if (rc != EOK) {
 
124
                async_exchange_end(exch);
 
125
                async_forget(req);
 
126
                return rc;
 
127
        }
 
128
 
 
129
        ipc_call_t answer_local;
 
130
        aid_t req_local = async_data_read(exch, local, sizeof(*local),
 
131
            &answer_local);
 
132
 
106
133
        async_exchange_end(exch);
107
 
        
108
 
        if (rc != EOK)
109
 
                return rc;
110
 
        
111
 
        *local = (uint32_t) local_addr;
112
 
        return EOK;
 
134
 
 
135
        sysarg_t retval_local;
 
136
        async_wait_for(req_local, &retval_local);
 
137
 
 
138
        if (retval_local != EOK) {
 
139
                async_forget(req);
 
140
                return (int) retval_local;
 
141
        }
 
142
 
 
143
        sysarg_t retval;
 
144
        async_wait_for(req, &retval);
 
145
 
 
146
        return (int) retval;
113
147
}
114
148
 
115
 
static void inetping_ev_recv(ipc_callid_t callid, ipc_call_t *call)
 
149
static void inetping_ev_recv(ipc_callid_t iid, ipc_call_t *icall)
116
150
{
117
151
        inetping_sdu_t sdu;
118
 
        
119
 
        sdu.src = IPC_GET_ARG1(*call);
120
 
        sdu.dest = IPC_GET_ARG2(*call);
121
 
        sdu.seq_no = IPC_GET_ARG3(*call);
122
 
        
123
 
        int rc = async_data_write_accept(&sdu.data, false, 0, 0, 0, &sdu.size);
124
 
        if (rc != EOK) {
125
 
                async_answer_0(callid, rc);
126
 
                return;
127
 
        }
128
 
        
 
152
 
 
153
        sdu.seq_no = IPC_GET_ARG1(*icall);
 
154
 
 
155
        ipc_callid_t callid;
 
156
        size_t size;
 
157
        if (!async_data_write_receive(&callid, &size)) {
 
158
                async_answer_0(callid, EREFUSED);
 
159
                async_answer_0(iid, EREFUSED);
 
160
                return;
 
161
        }
 
162
 
 
163
        if (size != sizeof(sdu.src)) {
 
164
                async_answer_0(callid, EINVAL);
 
165
                async_answer_0(iid, EINVAL);
 
166
                return;
 
167
        }
 
168
 
 
169
        int rc = async_data_write_finalize(callid, &sdu.src, size);
 
170
        if (rc != EOK) {
 
171
                async_answer_0(callid, rc);
 
172
                async_answer_0(iid, rc);
 
173
                return;
 
174
        }
 
175
 
 
176
        if (!async_data_write_receive(&callid, &size)) {
 
177
                async_answer_0(callid, EREFUSED);
 
178
                async_answer_0(iid, EREFUSED);
 
179
                return;
 
180
        }
 
181
 
 
182
        if (size != sizeof(sdu.dest)) {
 
183
                async_answer_0(callid, EINVAL);
 
184
                async_answer_0(iid, EINVAL);
 
185
                return;
 
186
        }
 
187
 
 
188
        rc = async_data_write_finalize(callid, &sdu.dest, size);
 
189
        if (rc != EOK) {
 
190
                async_answer_0(callid, rc);
 
191
                async_answer_0(iid, rc);
 
192
                return;
 
193
        }
 
194
 
 
195
        rc = async_data_write_accept(&sdu.data, false, 0, 0, 0, &sdu.size);
 
196
        if (rc != EOK) {
 
197
                async_answer_0(iid, rc);
 
198
                return;
 
199
        }
 
200
 
129
201
        rc = inetping_ev_ops->recv(&sdu);
130
202
        free(sdu.data);
131
 
        async_answer_0(callid, rc);
 
203
        async_answer_0(iid, rc);
132
204
}
133
205
 
134
206
static void inetping_cb_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)