This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/baseband-devel@lists.osmocom.org/.
Harald Welte laforge at gnumonks.orginstead of gsm322_msgb_alloc() followed by a sendmsg with intermittent error checks we now have only a single function call. --- .../layer23/include/osmocom/bb/mobile/gsm322.h | 7 +- src/host/layer23/src/mobile/app_mobile.c | 13 +-- src/host/layer23/src/mobile/gsm322.c | 69 ++++++++++++++- src/host/layer23/src/mobile/gsm48_mm.c | 88 +++++--------------- src/host/layer23/src/mobile/gsm48_rr.c | 33 +++----- src/host/layer23/src/mobile/vty_interface.c | 31 +++---- 6 files changed, 118 insertions(+), 123 deletions(-) diff --git a/src/host/layer23/include/osmocom/bb/mobile/gsm322.h b/src/host/layer23/include/osmocom/bb/mobile/gsm322.h index 467ff39..3cd275f 100644 --- a/src/host/layer23/include/osmocom/bb/mobile/gsm322.h +++ b/src/host/layer23/include/osmocom/bb/mobile/gsm322.h @@ -172,10 +172,9 @@ struct gsm322_msg { int gsm322_init(struct osmocom_ms *ms); int gsm322_exit(struct osmocom_ms *ms); -struct msgb *gsm322_msgb_alloc(int msg_type); -int gsm322_plmn_sendmsg(struct osmocom_ms *ms, struct msgb *msg); -int gsm322_cs_sendmsg(struct osmocom_ms *ms, struct msgb *msg); -int gsm322_c_event(struct osmocom_ms *ms, struct msgb *msg); +int gsm322_makesend_plmn_msg(struct osmocom_ms *ms, int msg_type, uint8_t *data, unsigned int len); +int gsm322_makesend_cs_event(struct osmocom_ms *ms, int msg_type, uint8_t *data, unsigned int len); +int gsm322_makesend_c_event(struct osmocom_ms *ms, int msg_type, uint8_t *data, unsigned int len); int gsm322_plmn_dequeue(struct osmocom_ms *ms); int gsm322_cs_dequeue(struct osmocom_ms *ms); int gsm322_add_forbidden_la(struct osmocom_ms *ms, uint16_t mcc, diff --git a/src/host/layer23/src/mobile/app_mobile.c b/src/host/layer23/src/mobile/app_mobile.c index 822ea64..3d2100c 100644 --- a/src/host/layer23/src/mobile/app_mobile.c +++ b/src/host/layer23/src/mobile/app_mobile.c @@ -79,7 +79,6 @@ int mobile_signal_cb(unsigned int subsys, unsigned int signal, { struct osmocom_ms *ms; struct gsm_settings *set; - struct msgb *nmsg; if (subsys != SS_L1CTL) return 0; @@ -105,14 +104,10 @@ int mobile_signal_cb(unsigned int subsys, unsigned int signal, break; default: /* no SIM, trigger PLMN selection process */ - nmsg = gsm322_msgb_alloc(GSM322_EVENT_SWITCH_ON); - if (!nmsg) - return -ENOMEM; - gsm322_plmn_sendmsg(ms, nmsg); - nmsg = gsm322_msgb_alloc(GSM322_EVENT_SWITCH_ON); - if (!nmsg) - return -ENOMEM; - gsm322_cs_sendmsg(ms, nmsg); + gsm322_makesend_plmn_msg(ms, GSM322_EVENT_SWITCH_ON, + NULL, 0); + gsm322_makesend_cs_event(ms, GSM322_EVENT_SWITCH_ON, + NULL, 0); } ms->started = 1; diff --git a/src/host/layer23/src/mobile/gsm322.c b/src/host/layer23/src/mobile/gsm322.c index 3c920e4..1429737 100644 --- a/src/host/layer23/src/mobile/gsm322.c +++ b/src/host/layer23/src/mobile/gsm322.c @@ -45,6 +45,8 @@ static void gsm322_cs_loss(void *arg); static int gsm322_cs_select(struct osmocom_ms *ms, int any, int plmn_allowed); static int gsm322_m_switch_on(struct osmocom_ms *ms, struct msgb *msg); +static int gsm322_c_event(struct osmocom_ms *ms, struct msgb *msg); + #define SKIP_MAX_PER_BAND #warning HACKING!!! @@ -182,7 +184,7 @@ const char *get_event_name(int value) /* allocate a 03.22 event message */ -struct msgb *gsm322_msgb_alloc(int msg_type) +static struct msgb *gsm322_msgb_alloc(int msg_type) { struct msgb *msg; struct gsm322_msg *gm; @@ -198,7 +200,7 @@ struct msgb *gsm322_msgb_alloc(int msg_type) } /* queue PLMN selection message */ -int gsm322_plmn_sendmsg(struct osmocom_ms *ms, struct msgb *msg) +static int gsm322_plmn_sendmsg(struct osmocom_ms *ms, struct msgb *msg) { struct gsm322_plmn *plmn = &ms->plmn; @@ -208,7 +210,7 @@ int gsm322_plmn_sendmsg(struct osmocom_ms *ms, struct msgb *msg) } /* queue cell selection message */ -int gsm322_cs_sendmsg(struct osmocom_ms *ms, struct msgb *msg) +static int gsm322_cs_sendmsg(struct osmocom_ms *ms, struct msgb *msg) { struct gsm322_cellsel *cs = &ms->cellsel; @@ -3304,7 +3306,7 @@ static struct cellselstatelist { #define CELLSELSLLEN \ (sizeof(cellselstatelist) / sizeof(struct cellselstatelist)) -int gsm322_c_event(struct osmocom_ms *ms, struct msgb *msg) +static int gsm322_c_event(struct osmocom_ms *ms, struct msgb *msg) { struct gsm322_cellsel *cs = &ms->cellsel; struct gsm322_msg *gm = (struct gsm322_msg *) msg->data; @@ -3602,4 +3604,63 @@ int gsm322_exit(struct osmocom_ms *ms) return 0; } +int gsm322_makesend_c_event(struct osmocom_ms *ms, int msg_type, + uint8_t *data, unsigned int len) +{ + struct msgb *nmsg = gsm322_msgb_alloc(msg_type); + int rc; + if (!nmsg) + return -ENOMEM; + + if (data && len) { + uint8_t *cur = msgb_push(nmsg, len); + if (!cur) { + msgb_free(nmsg); + return -EIO; + } + memcpy(cur, data, len); + } + rc = gsm322_c_event(ms, nmsg); + msgb_free(nmsg); + + return rc; +} + +int gsm322_makesend_cs_event(struct osmocom_ms *ms, int msg_type, + uint8_t *data, unsigned int len) +{ + struct msgb *nmsg = gsm322_msgb_alloc(msg_type); + + if (!nmsg) + return -ENOMEM; + + if (data && len) { + uint8_t *cur = msgb_push(nmsg, len); + if (!cur) { + msgb_free(nmsg); + return -EIO; + } + memcpy(cur, data, len); + } + return gsm322_cs_sendmsg(ms, nmsg); +} + +int gsm322_makesend_plmn_msg(struct osmocom_ms *ms, int msg_type, + uint8_t *data, unsigned int len) +{ + struct msgb *nmsg = gsm322_msgb_alloc(msg_type); + + if (!nmsg) + return -ENOMEM; + + if (data && len) { + uint8_t *cur = msgb_push(nmsg, len); + if (!cur) { + msgb_free(nmsg); + return -EIO; + } + memcpy(cur, data, len); + } + return gsm322_plmn_sendmsg(ms, nmsg); +} diff --git a/src/host/layer23/src/mobile/gsm48_mm.c b/src/host/layer23/src/mobile/gsm48_mm.c index 15bbd27..58253bd 100644 --- a/src/host/layer23/src/mobile/gsm48_mm.c +++ b/src/host/layer23/src/mobile/gsm48_mm.c @@ -1118,33 +1118,23 @@ static int gsm48_mm_cell_selected(struct osmocom_ms *ms, struct msgb *msg) && cs->sel_lac == subscr->lac && !mm->lupd_periodic) { if (subscr->imsi_attached) { - struct msgb *nmsg; - LOGP(DMM, LOGL_INFO, "Valid in location area.\n"); new_mm_state(mm, GSM48_MM_ST_MM_IDLE, GSM48_MM_SST_NORMAL_SERVICE); /* send message to PLMN search process */ - nmsg = gsm322_msgb_alloc(GSM322_EVENT_REG_SUCCESS); - if (!nmsg) - return -ENOMEM; - gsm322_plmn_sendmsg(ms, nmsg); - + gsm322_makesend_plmn_msg(ms, GSM322_EVENT_REG_SUCCESS, + NULL, 0); return 0; } if (!s->att_allowed) { - struct msgb *nmsg; - LOGP(DMM, LOGL_INFO, "Attachment not required.\n"); new_mm_state(mm, GSM48_MM_ST_MM_IDLE, GSM48_MM_SST_NORMAL_SERVICE); /* send message to PLMN search process */ - nmsg = gsm322_msgb_alloc(GSM322_EVENT_REG_SUCCESS); - if (!nmsg) - return -ENOMEM; - gsm322_plmn_sendmsg(ms, nmsg); - + gsm322_makesend_plmn_msg(ms, GSM322_EVENT_REG_SUCCESS, + NULL, 0); return 0; } /* else, continue */ @@ -1155,17 +1145,13 @@ static int gsm48_mm_cell_selected(struct osmocom_ms *ms, struct msgb *msg) && (gsm_subscr_is_forbidden_plmn(subscr, cs->sel_mcc, cs->sel_mnc) || gsm322_is_forbidden_la(ms, cs->sel_mcc, cs->sel_mnc, cs->sel_lac))) { - struct msgb *nmsg; - LOGP(DMM, LOGL_INFO, "Selected cell is forbidden.\n"); new_mm_state(mm, GSM48_MM_ST_MM_IDLE, GSM48_MM_SST_LIMITED_SERVICE); /* send message to PLMN search process */ - nmsg = gsm322_msgb_alloc(GSM322_EVENT_ROAMING_NA); - if (!nmsg) - return -ENOMEM; - gsm322_plmn_sendmsg(ms, nmsg); + gsm322_makesend_plmn_msg(ms, GSM322_EVENT_ROAMING_NA, + NULL, 0); return 0; } @@ -1174,17 +1160,12 @@ static int gsm48_mm_cell_selected(struct osmocom_ms *ms, struct msgb *msg) if (set->plmn_mode == PLMN_MODE_MANUAL && (plmn->mcc != cs->sel_mcc || plmn->mnc != cs->sel_mnc)) { - struct msgb *nmsg; - LOGP(DMM, LOGL_INFO, "Selected cell not found.\n"); new_mm_state(mm, GSM48_MM_ST_MM_IDLE, GSM48_MM_SST_LIMITED_SERVICE); /* send message to PLMN search process */ - nmsg = gsm322_msgb_alloc(GSM322_EVENT_REG_FAILED); - if (!nmsg) - return -ENOMEM; - gsm322_plmn_sendmsg(ms, nmsg); + gsm322_makesend_plmn_msg(ms, GSM322_EVENT_REG_FAILED, NULL, 0); return 0; } @@ -1729,7 +1710,6 @@ static int gsm48_mm_imsi_detach_end(struct osmocom_ms *ms, struct msgb *msg) { struct gsm48_mmlayer *mm = &ms->mmlayer; struct gsm_subscriber *subscr = &ms->subscr; - struct msgb *nmsg; LOGP(DMM, LOGL_INFO, "IMSI has been detached.\n"); @@ -1753,10 +1733,7 @@ static int gsm48_mm_imsi_detach_end(struct osmocom_ms *ms, struct msgb *msg) } /* send SIM remove event to gsm322 */ - nmsg = gsm322_msgb_alloc(GSM322_EVENT_SIM_REMOVE); - if (!nmsg) - return -ENOMEM; - gsm322_plmn_sendmsg(ms, nmsg); + gsm322_makesend_plmn_msg(ms, GSM322_EVENT_SIM_REMOVE, NULL, 0); /* CS process will trigger return to MM IDLE / No SIM */ return 0; @@ -1999,7 +1976,6 @@ static int gsm48_mm_loc_upd(struct osmocom_ms *ms, struct msgb *msg) struct gsm48_sysinfo *s = &cs->sel_si; struct gsm_subscriber *subscr = &ms->subscr; struct gsm_settings *set = &ms->settings; - struct msgb *nmsg; int msg_type; /* (re)start only if we still require location update */ @@ -2017,10 +1993,7 @@ static int gsm48_mm_loc_upd(struct osmocom_ms *ms, struct msgb *msg) _stop: mm->lupd_pending = 0; /* send message to PLMN search process */ - nmsg = gsm322_msgb_alloc(msg_type); - if (!nmsg) - return -ENOMEM; - gsm322_plmn_sendmsg(ms, nmsg); + gsm322_makesend_plmn_msg(ms, msg_type, NULL, 0); return 0; } @@ -2076,7 +2049,6 @@ static int gsm48_mm_loc_upd_normal(struct osmocom_ms *ms, struct msgb *msg) struct gsm_subscriber *subscr = &ms->subscr; struct gsm322_cellsel *cs = &ms->cellsel; struct gsm48_sysinfo *s = &cs->sel_si; - struct msgb *nmsg; /* in case we already have a location update going on */ if (mm->lupd_pending) { @@ -2090,10 +2062,7 @@ static int gsm48_mm_loc_upd_normal(struct osmocom_ms *ms, struct msgb *msg) LOGP(DMM, LOGL_INFO, "Loc. upd. not allowed.\n"); /* send message to PLMN search process */ - nmsg = gsm322_msgb_alloc(GSM322_EVENT_REG_FAILED); - if (!nmsg) - return -ENOMEM; - gsm322_plmn_sendmsg(ms, nmsg); + gsm322_makesend_plmn_msg(ms, GSM322_EVENT_REG_FAILED, NULL, 0); return 0; } @@ -2114,10 +2083,7 @@ static int gsm48_mm_loc_upd_normal(struct osmocom_ms *ms, struct msgb *msg) GSM48_MM_SST_NORMAL_SERVICE); /* send message to PLMN search process */ - nmsg = gsm322_msgb_alloc(GSM322_EVENT_REG_SUCCESS); - if (!nmsg) - return -ENOMEM; - gsm322_plmn_sendmsg(ms, nmsg); + gsm322_makesend_plmn_msg(ms, GSM322_EVENT_REG_SUCCESS, NULL, 0); return 0; } @@ -2256,7 +2222,6 @@ static int gsm48_mm_rx_loc_upd_acc(struct osmocom_ms *ms, struct msgb *msg) struct gsm48_loc_area_id *lai = (struct gsm48_loc_area_id *) gh->data; unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh); struct tlv_parsed tp; - struct msgb *nmsg; if (payload_len < sizeof(struct gsm48_loc_area_id)) { short_read: @@ -2353,10 +2318,7 @@ static int gsm48_mm_rx_loc_upd_acc(struct osmocom_ms *ms, struct msgb *msg) } /* send message to PLMN search process */ - nmsg = gsm322_msgb_alloc(GSM322_EVENT_REG_SUCCESS); - if (!nmsg) - return -ENOMEM; - gsm322_plmn_sendmsg(ms, nmsg); + gsm322_makesend_plmn_msg(ms, GSM322_EVENT_REG_SUCCESS, NULL, 0); /* follow on proceed */ if (TLVP_PRESENT(&tp, GSM48_IE_MOBILE_ID)) @@ -2408,8 +2370,8 @@ static int gsm48_mm_rel_loc_upd_rej(struct osmocom_ms *ms, struct msgb *msg) { struct gsm48_mmlayer *mm = &ms->mmlayer; struct gsm_subscriber *subscr = &ms->subscr; - struct msgb *nmsg; - struct gsm322_msg *ngm; + struct gsm322_msg ngm; + int msg_type; LOGP(DMM, LOGL_INFO, "Loc. upd. rejected (cause %d)\n", mm->lupd_rej_cause); @@ -2450,23 +2412,21 @@ static int gsm48_mm_rel_loc_upd_rej(struct osmocom_ms *ms, struct msgb *msg) } /* send event to PLMN search process */ - switch(mm->lupd_rej_cause) { + switch (mm->lupd_rej_cause) { case GSM48_REJECT_ROAMING_NOT_ALLOWED: - nmsg = gsm322_msgb_alloc(GSM322_EVENT_ROAMING_NA); + msg_type = GSM322_EVENT_ROAMING_NA; break; case GSM48_REJECT_IMSI_UNKNOWN_IN_HLR: case GSM48_REJECT_ILLEGAL_MS: case GSM48_REJECT_ILLEGAL_ME: - nmsg = gsm322_msgb_alloc(GSM322_EVENT_INVALID_SIM); + msg_type = GSM322_EVENT_INVALID_SIM; break; default: - nmsg = gsm322_msgb_alloc(GSM322_EVENT_REG_FAILED); + msg_type = GSM322_EVENT_REG_FAILED; } - if (!nmsg) - return -ENOMEM; - ngm = (struct gsm322_msg *)nmsg->data; - ngm->reject = mm->lupd_rej_cause; - gsm322_plmn_sendmsg(ms, nmsg); + memset(&ngm, 0, sizeof(ngm)); + ngm.reject = mm->lupd_rej_cause; + gsm322_makesend_plmn_msg(ms, msg_type, NULL, 0); /* forbidden list */ switch (mm->lupd_rej_cause) { @@ -4106,13 +4066,9 @@ static int gsm48_mm_ev(struct osmocom_ms *ms, int msg_type, struct msgb *msg) static int gsm48_mmr_reg_req(struct osmocom_ms *ms) { struct gsm48_mmlayer *mm = &ms->mmlayer; - struct msgb *nmsg; /* schedule insertion of SIM */ - nmsg = gsm322_msgb_alloc(GSM322_EVENT_SIM_INSERT); - if (!nmsg) - return -ENOMEM; - gsm322_plmn_sendmsg(ms, nmsg); + gsm322_makesend_plmn_msg(ms, GSM322_EVENT_SIM_INSERT, NULL, 0); /* 4.2.1.2 SIM is inserted in state NO IMSI */ if (mm->state == GSM48_MM_ST_MM_IDLE diff --git a/src/host/layer23/src/mobile/gsm48_rr.c b/src/host/layer23/src/mobile/gsm48_rr.c index dc2226a..4a48dc8 100644 --- a/src/host/layer23/src/mobile/gsm48_rr.c +++ b/src/host/layer23/src/mobile/gsm48_rr.c @@ -375,8 +375,8 @@ static void new_rr_state(struct gsm48_rrlayer *rr, int state) rr->state = state; if (state == GSM48_RR_ST_IDLE) { - struct msgb *msg, *nmsg; - struct gsm322_msg *em; + struct msgb *msg; + struct gsm322_msg em; /* release dedicated mode, if any */ l1ctl_tx_dm_rel_req(rr->ms); @@ -403,16 +403,13 @@ static void new_rr_state(struct gsm48_rrlayer *rr, int state) * cell selection process returned to camping state * again. (after cell reselection) */ - nmsg = gsm322_msgb_alloc(GSM322_EVENT_RET_IDLE); - if (!nmsg) - return; /* return to same cell after LOC.UPD. */ if (rr->est_cause == RR_EST_CAUSE_LOC_UPD) { - em = (struct gsm322_msg *) nmsg->data; - em->same_cell = 1; + memset(&em, 0, sizeof(em)); + em.same_cell = 1; } - gsm322_c_event(rr->ms, nmsg); - msgb_free(nmsg); + gsm322_makesend_c_event(rr->ms, GSM322_EVENT_RET_IDLE, + (uint8_t *)&em, sizeof(em)); /* reset any BA range */ rr->ba_ranges = 0; } @@ -1192,11 +1189,7 @@ static int gsm48_rr_chan_req(struct osmocom_ms *ms, int cause, int paging) * NOTE: this must be sent unbuffered, because the state may not * change until idle mode is left */ - nmsg = gsm322_msgb_alloc(GSM322_EVENT_LEAVE_IDLE); - if (!nmsg) - return -ENOMEM; - rc = gsm322_c_event(ms, nmsg); - msgb_free(nmsg); + rc = gsm322_makesend_c_event(ms, GSM322_EVENT_LEAVE_IDLE, NULL, 0); if (rc) { if (paging) return rc; @@ -1567,7 +1560,7 @@ static int gsm48_new_sysinfo(struct osmocom_ms *ms, uint8_t type) { struct gsm48_sysinfo *s = ms->cellsel.si; struct msgb *nmsg; - struct gsm322_msg *em; + struct gsm322_msg em; /* update list of measurements, if BA(SACCH) is complete and new */ if (s @@ -1600,12 +1593,10 @@ static int gsm48_new_sysinfo(struct osmocom_ms *ms, uint8_t type) } /* send sysinfo event to other layers */ - nmsg = gsm322_msgb_alloc(GSM322_EVENT_SYSINFO); - if (!nmsg) - return -ENOMEM; - em = (struct gsm322_msg *) nmsg->data; - em->sysinfo = type; - gsm322_cs_sendmsg(ms, nmsg); + memset(&em, 0, sizeof(em)); + em.sysinfo = type; + gsm322_makesend_cs_event(ms, GSM322_EVENT_SYSINFO, + (uint8_t *)&em, sizeof(em)); /* send timer info to location update process */ nmsg = gsm48_mmevent_msgb_alloc(GSM48_MM_EVENT_SYSINFO); diff --git a/src/host/layer23/src/mobile/vty_interface.c b/src/host/layer23/src/mobile/vty_interface.c index 4cc2209..e3e7c47 100644 --- a/src/host/layer23/src/mobile/vty_interface.c +++ b/src/host/layer23/src/mobile/vty_interface.c @@ -658,8 +658,7 @@ DEFUN(network_select, network_select_cmd, "network select MS_NAME MCC MNC", { struct osmocom_ms *ms; struct gsm322_plmn *plmn; - struct msgb *nmsg; - struct gsm322_msg *ngm; + struct gsm322_msg ngm; struct gsm322_plmn_list *temp; uint16_t mcc = gsm_input_mcc((char *)argv[1]), mnc = gsm_input_mnc((char *)argv[2]); @@ -687,13 +686,11 @@ DEFUN(network_select, network_select_cmd, "network select MS_NAME MCC MNC", return CMD_WARNING; } - nmsg = gsm322_msgb_alloc(GSM322_EVENT_CHOOSE_PLMN); - if (!nmsg) - return CMD_WARNING; - ngm = (struct gsm322_msg *) nmsg->data; - ngm->mcc = mcc; - ngm->mnc = mnc; - gsm322_plmn_sendmsg(ms, nmsg); + memset(&ngm, 0, sizeof(ngm)); + ngm.mcc = mcc; + ngm.mnc = mnc; + gsm322_makesend_plmn_msg(ms, GSM322_EVENT_CHOOSE_PLMN, + (uint8_t *)&ngm, sizeof(ngm)); return CMD_SUCCESS; } @@ -818,16 +815,12 @@ DEFUN(network_search, network_search_cmd, "network search MS_NAME", "Network ...\nTrigger network search\nName of MS (see \"show ms\")") { struct osmocom_ms *ms; - struct msgb *nmsg; ms = get_ms(argv[0], vty); if (!ms) return CMD_WARNING; - nmsg = gsm322_msgb_alloc(GSM322_EVENT_USER_RESEL); - if (!nmsg) - return CMD_WARNING; - gsm322_plmn_sendmsg(ms, nmsg); + gsm322_makesend_plmn_msg(ms, GSM322_EVENT_USER_RESEL, NULL, 0); return CMD_SUCCESS; } @@ -1256,7 +1249,7 @@ DEFUN(cfg_ms_mode, cfg_ms_mode_cmd, "network-selection-mode (auto|manual)", { struct osmocom_ms *ms = vty->index; struct gsm_settings *set = &ms->settings; - struct msgb *nmsg; + int msg_type = -1; if (!ms->plmn.state) { if (argv[0][0] == 'a') @@ -1267,12 +1260,12 @@ DEFUN(cfg_ms_mode, cfg_ms_mode_cmd, "network-selection-mode (auto|manual)", return CMD_SUCCESS; } if (argv[0][0] == 'a') - nmsg = gsm322_msgb_alloc(GSM322_EVENT_SEL_AUTO); + msg_type = GSM322_EVENT_SEL_AUTO; else - nmsg = gsm322_msgb_alloc(GSM322_EVENT_SEL_MANUAL); - if (!nmsg) + msg_type = GSM322_EVENT_SEL_MANUAL; + if (msg_type < 0) return CMD_WARNING; - gsm322_plmn_sendmsg(ms, nmsg); + gsm322_makesend_plmn_msg(ms, msg_type, NULL, 0); return CMD_SUCCESS; } -- 1.7.2.3 --Kj7319i9nmIyA2yE Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="0002-mobile-replace-3-different-gsm322_makesend_-function.patch"