4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Kyoungyoup Park <gynaru.park@samsung.com>
7 * Hayoon Ko <hayoon.ko@samsung.com>
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
28 #include <arpa/inet.h>
34 #include <core_object.h>
38 #include <co_context.h>
39 #include <user_request.h>
46 #include "atchannel.h"
49 extern struct ATResponse *sp_response;
50 extern char *s_responsePrefix;
51 extern enum ATCommandType s_type;
53 static void on_confirmation_ps_message_send( TcorePending *p, gboolean result, void *user_data )
55 UserRequest* ur = NULL;
56 struct ATReqMetaInfo* metainfo = NULL;
57 unsigned int info_len =0;
58 dbg("on_confirmation_ps_message_send - msg out from queue. alloc ATRsp buffer & write rspPrefix if needed\n");
60 ReleaseResponse(); // release leftover
61 //alloc new sp_response
62 sp_response = at_response_new();
64 ur = tcore_pending_ref_user_request(p);
65 metainfo = (struct ATReqMetaInfo*)tcore_user_request_ref_metainfo(ur,&info_len);
67 if ((metainfo->type == SINGLELINE)||(metainfo->type == MULTILINE)) {
69 s_responsePrefix = strdup(metainfo->responsePrefix);
70 dbg("duplicating responsePrefix : %s\n", s_responsePrefix);
73 s_responsePrefix = NULL;
76 //set atcmd type into s_type
77 s_type = metainfo->type;
79 if (result == FALSE) {
89 static TReturn _pdp_device_control(gboolean flag, unsigned int context_id)
97 return TCORE_RETURN_EINVAL;
100 control = "/sys/class/net/svnet0/pdp/activate";
102 control = "/sys/class/net/svnet0/pdp/deactivate";
104 fd = open(control, O_WRONLY);
106 return TCORE_RETURN_FAILURE;
109 snprintf(buf, sizeof(buf), "%d", context_id);
110 size = write(fd, buf, strlen(buf));
113 return TCORE_RETURN_SUCCESS;
116 static void on_event_ps_ipconfiguration(CoreObject *o, const void *event_info, void *user_data)
118 /* Parsing the response line and map into noti. */
119 CoreObject *ps_context = (CoreObject *)user_data;
120 unsigned int pdpContextCnt, cid = tcore_context_get_id(ps_context);
121 struct ATLine *p_cur = NULL;
122 const struct ATResponse *p_response = event_info;
123 int err, ret, p_cid=0, d_comp = -1, h_comp = -1;
124 struct tnoti_ps_pdp_ipconfiguration noti;
125 char devname[10] = {0,};
126 char addr_buf[5][20];
127 char *pdp_type = NULL, *apn = NULL;
128 char *line = NULL, *ip = NULL, *gateway = NULL;//, *netmask = NULL;
130 /* count the PDP contexts */
131 for (pdpContextCnt = 0, p_cur = p_response->p_intermediates
133 ; p_cur = p_cur->p_next) {
137 dbg("Total number of PDP contexts : %d",pdpContextCnt);
139 if(pdpContextCnt == 0)
142 for (p_cur = p_response->p_intermediates
144 ; p_cur = p_cur->p_next) {
145 line = p_response->p_intermediates->line;
147 err = at_tok_start(&line);
148 err = at_tok_nextint(&line,&p_cid);
149 dbg("cid: %d", p_cid);
151 /* Send IP Configuration noti only on the requested CID. */
152 if (p_cid && (cid == (unsigned int)p_cid)) {
153 err = at_tok_nextstr(&line,&pdp_type);
154 dbg("PDP type: %s", pdp_type);
156 if (pdp_type!=NULL) {
157 err = at_tok_nextstr(&line,&apn);
161 err = at_tok_nextstr(&line,&ip);
162 dbg("IP address: %s", ip);
165 err = at_tok_nextint(&line,&d_comp);
166 dbg("d_comp: %d", d_comp);
169 err = at_tok_nextint(&line,&h_comp);
170 dbg("h_comp: %d", h_comp);
173 memset(¬i, 0, sizeof(struct tnoti_ps_pdp_ipconfiguration));
175 noti.context_id = cid;
178 /* Just use AF_INET here. */
179 ret = inet_pton(AF_INET, ip, ¬i.ip_address);
181 dbg("inet_pton() failed.");
185 snprintf(addr_buf[0], 20, "%d.%d.%d.%d", noti.ip_address[0], noti.ip_address[1],
186 noti.ip_address[2], noti.ip_address[3]);
188 dbg("ip = [%s]", ip);
190 noti.primary_dns[0] = 8;
191 noti.primary_dns[1] = 8;
192 noti.primary_dns[2] = 8;
193 noti.primary_dns[3] = 8;
194 dbg("primary_dns = [8.8.8.8] Public DNS server.");
196 noti.secondary_dns[0] = 8;
197 noti.secondary_dns[1] = 8;
198 noti.secondary_dns[2] = 4;
199 noti.secondary_dns[3] = 4;
200 dbg("secondary_dns = [8.8.4.4] Public DNS server.");
202 memcpy(¬i.gateway, ¬i.ip_address, 4);
204 snprintf(addr_buf[3], 20, "%d.%d.%d.%d", noti.gateway[0], noti.gateway[1], noti.gateway[2],
206 gateway = addr_buf[3];
207 dbg("gateway = [%s]", gateway);
209 /* FIX ME: use static netmask. */
210 noti.subnet_mask[0] = 255;
211 noti.subnet_mask[1] = 255;
212 noti.subnet_mask[2] = 255;
213 noti.subnet_mask[3] = 0;
214 dbg("subnet_mask = [255.255.255.0]");
216 if (_pdp_device_control(TRUE, cid) != TCORE_RETURN_SUCCESS) {
217 dbg("_pdp_device_control() failed. errno=%d", errno);
220 snprintf(devname, 10, "pdp%d", cid - 1);
221 memcpy(noti.devname, devname, 10);
222 dbg("devname = [%s]", devname);
224 if (tcore_util_netif_up(devname) != TCORE_RETURN_SUCCESS) {
225 dbg("util_netif_up() failed. errno=%d", errno);
227 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_PS_PDP_IPCONFIGURATION,
228 sizeof(struct tnoti_ps_pdp_ipconfiguration), ¬i);
231 dbg("No matched response with CID: %d",cid);
235 static void on_response_get_ipconfiguration(TcorePending *pending, int data_len, const void *data, void *user_data)
237 struct ATLine *p_cur;
238 CoreObject *ps_context = (CoreObject *)user_data;
243 if (sp_response->success > 0) {
246 for (p_cur = sp_response->p_intermediates
248 ; p_cur = p_cur->p_next) {
249 line = sp_response->p_intermediates->line;
253 dbg("Call on_ipc_event_ps_ipconfiguration");
254 on_event_ps_ipconfiguration(tcore_pending_ref_core_object(pending), sp_response, ps_context);
263 static void on_response_ps_attached(TcorePending *p, int data_len, const void *data, void *user_data)
265 TcorePlugin *pl = NULL;
267 TcorePending *pending = NULL;
268 CoreObject *o = tcore_pending_ref_core_object(p);
269 CoreObject *ps_context = (CoreObject *)user_data;
272 char* cmd_str = NULL;
273 struct ATReqMetaInfo metainfo;
279 if (sp_response->success > 0) {
281 line = sp_response->p_intermediates->line;
282 dbg("on_response_ps_attached: %s", line);
284 ur = tcore_user_request_new(NULL, NULL);
285 memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
286 memcpy(metainfo.responsePrefix,"+CGDCONT:",strlen("+CGDCONT:"));
287 metainfo.type = MULTILINE;
288 info_len = sizeof(struct ATReqMetaInfo);
290 tcore_user_request_set_metainfo(ur, info_len, &metainfo);
292 dbg(" Send: AT+CGDCONT?\r ");
293 cmd_str = g_strdup("AT+CGDCONT?\r");
295 pl = tcore_object_ref_plugin(o);
296 h = tcore_object_get_hal(o);
297 pending = tcore_pending_new(o, ID_RESERVED_AT);
298 tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
301 tcore_pending_set_timeout(pending, 0);
302 tcore_pending_set_response_callback(pending, on_response_get_ipconfiguration, ps_context);
303 tcore_pending_link_user_request(pending, ur);
304 tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
305 tcore_pending_set_send_callback(pending, on_confirmation_ps_message_send, NULL);
306 tcore_hal_send_request(h, pending);
315 static void on_response_active_set(TcorePending *p, int data_len, const void *data, void *user_data)
317 TcorePlugin *pl = NULL;
319 TcorePending *pending = NULL;
320 CoreObject *o = tcore_pending_ref_core_object(p);
321 CoreObject *ps_context = (CoreObject *)user_data;
324 char* cmd_str = NULL;
325 struct ATReqMetaInfo metainfo;
330 if (sp_response->success > 0) {
333 ur = tcore_user_request_new(NULL, NULL);
334 memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
335 metainfo.type = SINGLELINE;
336 info_len = sizeof(struct ATReqMetaInfo);
338 tcore_user_request_set_metainfo(ur, info_len, &metainfo);
340 dbg(" Send: ATD*99***1#\r ");
341 cmd_str = g_strdup("ATD*99***1#\r");
343 pl = tcore_object_ref_plugin(o);
344 h = tcore_object_get_hal(o);
345 pending = tcore_pending_new(o, ID_RESERVED_AT);
347 tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
350 tcore_pending_set_timeout(pending, 0);
351 tcore_pending_set_response_callback(pending, on_response_ps_attached, ps_context);
352 tcore_pending_link_user_request(pending, ur);
353 tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
354 tcore_pending_set_send_callback(pending, on_confirmation_ps_message_send, NULL);
355 tcore_hal_send_request(h, pending);
359 tcore_context_set_state(ps_context, CONTEXT_STATE_DEACTIVATED);
365 static void on_response_deactive_set(TcorePending *p, int data_len, const void *data, void *user_data)
369 if (sp_response->success > 0) {
379 static TReturn activate_ps_context(CoreObject *o, CoreObject *ps_context, void* user_data)
381 TcorePlugin *p = NULL;
383 TcorePending *pending = NULL;
387 char* cmd_str = NULL;
388 struct ATReqMetaInfo metainfo;
392 return TCORE_RETURN_FAILURE;
394 p = tcore_object_ref_plugin(o);
395 h = tcore_object_get_hal(o);
398 ur = tcore_user_request_new(NULL, NULL);
399 memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
400 metainfo.type = NO_RESULT;
401 info_len = sizeof(struct ATReqMetaInfo);
403 tcore_user_request_set_metainfo(ur, info_len, &metainfo);
405 cid = tcore_context_get_id(ps_context);
407 dbg("Example: AT+CGACT=1,0");
408 cmd_str = g_strdup_printf("%s=%d,%d%s","AT+CGACT", 1, cid, "\r");
410 pending = tcore_pending_new(o, ID_RESERVED_AT);
411 tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
414 tcore_pending_set_timeout(pending, 0);
415 tcore_pending_set_response_callback(pending, on_response_active_set, ps_context);
416 tcore_pending_link_user_request(pending, ur);
417 tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
418 tcore_pending_set_send_callback(pending, on_confirmation_ps_message_send, NULL);
419 tcore_hal_send_request(h, pending);
424 static void on_response_define_pdp(TcorePending *p, int data_len, const void *data, void *user_data)
426 //CoreObject *ps_context = user_data;
430 if (sp_response->success > 0) {
432 //pdp_active_set(tcore_pending_ref_core_object(p), ps_context);
436 tcore_context_set_state(tcore_pending_ref_core_object(p), CONTEXT_STATE_DEACTIVATED);
442 static TReturn define_ps_context(CoreObject *o, CoreObject *ps_context, void *user_data)
444 TcorePlugin *p = NULL;
446 TcorePending *pending = NULL;
449 char *apn=NULL, *addr=NULL;
452 enum co_context_type pdp_type;
453 enum co_context_d_comp d_comp;
454 enum co_context_h_comp h_comp;
455 char *cmd_str = NULL;
456 struct ATReqMetaInfo metainfo;
460 return TCORE_RETURN_FAILURE;
462 p = tcore_object_ref_plugin(o);
463 h = tcore_object_get_hal(o);
464 ur = tcore_user_request_new(NULL, NULL);
465 memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
466 metainfo.type = NO_RESULT;
467 info_len = sizeof(struct ATReqMetaInfo);
469 tcore_user_request_set_metainfo(ur, info_len, &metainfo);
471 cid = tcore_context_get_id(ps_context);
472 pdp_type = tcore_context_get_type(ps_context);
473 d_comp = tcore_context_get_data_compression(ps_context);
474 h_comp = tcore_context_get_header_compression(ps_context);
476 dbg("Example: AT+CGDCONT=1,\"IP\",\"www.example.co.kr\",,0,0");
477 cmd_str = g_strdup_printf("AT+CGDCONT=%d,\"%d\",\"%s\",%s,%d,%d%s",
478 cid, pdp_type, apn, addr, d_comp, h_comp, "\r");
480 pending = tcore_pending_new(o, ID_RESERVED_AT);
481 tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
484 tcore_pending_set_timeout(pending, 0);
485 tcore_pending_set_response_callback(pending, on_response_define_pdp, ps_context);
486 tcore_pending_link_user_request(pending, ur);
487 tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
488 tcore_pending_set_send_callback(pending, on_confirmation_ps_message_send, NULL);
489 tcore_hal_send_request(h, pending);
491 return TCORE_RETURN_SUCCESS;
494 static TReturn deactivate_ps_context(CoreObject *o, CoreObject *ps_context, void *user_data)
496 TcorePlugin *p = NULL;
498 TcorePending *pending = NULL;
502 char* cmd_str = NULL;
503 struct ATReqMetaInfo metainfo;
507 return TCORE_RETURN_FAILURE;
509 p = tcore_object_ref_plugin(o);
510 h = tcore_object_get_hal(o);
511 ur = tcore_user_request_new(NULL, NULL);
513 memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
514 metainfo.type = NO_RESULT;
515 info_len = sizeof(struct ATReqMetaInfo);
517 cid = tcore_context_get_id(ps_context);
519 dbg("Example: AT+CGACT=0,1");
520 cmd_str = g_strdup_printf("%s=%d,%d%s","AT+CGACT", 0, cid, "\r");
522 pending = tcore_pending_new(o, ID_RESERVED_AT);
523 tcore_pending_set_request_data(pending, strlen(cmd_str), cmd_str);
526 tcore_pending_set_timeout(pending, 0);
527 tcore_pending_set_response_callback(pending, on_response_deactive_set, ps_context);
528 tcore_pending_link_user_request(pending, ur);
529 tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
530 tcore_pending_set_send_callback(pending, on_confirmation_ps_message_send, NULL);
531 tcore_hal_send_request(h, pending);
533 return TCORE_RETURN_SUCCESS;
536 static struct tcore_ps_operations ps_ops =
538 .define_context = define_ps_context,
539 .activate_context = activate_ps_context,
540 .deactivate_context = deactivate_ps_context
543 gboolean s_ps_init(TcorePlugin *p, TcoreHal *h)
548 o = tcore_ps_new(p, "umts_ps", &ps_ops, h);
552 work_queue = g_queue_new();
553 tcore_object_link_user_data(o, work_queue);
558 void s_ps_exit(TcorePlugin *p)
563 o = tcore_plugin_ref_core_object(p, "umts_ps");
567 work_queue = tcore_object_ref_user_data(o);
569 g_queue_free(work_queue);